commit 79d67ea6a50b2538337c801cd1e63fbb523a61a8 Author: David Kifer Date: Tue Jun 23 15:48:14 2026 -0400 Initial commit of video upscaler diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..55b5e14 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Python +venv/ +.venv/ +__pycache__/ +*.pyc +*.pyo + +# Runtime data +uploads/ +outputs/ +temp/ +server.log +.uvicorn.pid + +# OS +.DS_Store +Thumbs.db + +# IDE +.vscode/ +.idea/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..f0f5166 --- /dev/null +++ b/README.md @@ -0,0 +1,150 @@ +# 🎬 AI Video Upscaler + +A web-based video upscaling application powered by [Real-ESRGAN ncnn-vulkan](https://github.com/xinntao/Real-ESRGAN). Upload your videos through an intuitive dashboard, select an AI model, and produce high-resolution output — all accelerated by your Vulkan-compatible GPU. + +--- + +## ✨ Features + +| Category | Details | +|---|---| +| **AI Upscaling** | 2×/3×/4× upscaling via Real-ESRGAN ncnn-vulkan with GPU acceleration | +| **Web Dashboard** | Modern browser UI for uploading, configuring, and monitoring jobs | +| **Multiple Models** | Choose from bundled models (realesrgan-x4plus, realesrgan-x4plus-anime, realesr-animevideov3, etc.) | +| **Custom Model Upload** | Upload your own `.param` / `.bin` model files through the UI | +| **Frame Preview** | Preview a single upscaled frame before committing to a full job | +| **Video Trimming** | Trim start/end times before upscaling to process only the segment you need | +| **Post-Processing Filters** | Optional sharpening, denoising, and color-correction filters applied after upscaling | +| **Audio & Subtitle Preservation** | Original audio tracks and subtitle streams are automatically muxed into the output | +| **Job Queue** | Queue multiple jobs and track progress in real time via WebSocket | +| **Webhook Notifications** | Configure a webhook URL to receive a callback when a job completes or fails | +| **System Diagnostics** | Built-in diagnostics endpoint reports GPU info, Vulkan status, disk space, and dependency versions | +| **Output Gallery** | Browse, preview, and download completed videos from the dashboard | + +--- + +## 📋 Requirements + +- **OS:** Linux x86_64 +- **Python:** 3.10+ +- **FFmpeg / FFprobe:** installed and available on `$PATH` +- **GPU:** Vulkan-compatible GPU (NVIDIA, AMD, or Intel) with up-to-date drivers + +--- + +## 🚀 Quick Start + +```bash +# 1. Clone the repository +git clone video_upscaler +cd video_upscaler + +# 2. Run the setup script (creates venv, installs deps, downloads Real-ESRGAN binary & models) +./setup.sh + +# 3. Start the server +python start.py +``` + +The dashboard will be available at **http://localhost:8000** (or your machine's network IP) by default. + +--- + +## 🖥️ Server Management + +```bash +python start.py # Start on default port 8000 (binds to 0.0.0.0 for LAN access) +python start.py --port 9000 # Start on a custom port +python start.py --host 127.0.0.1 # Bind to loopback only (no LAN access) +python start.py --no-browser # Don't open browser automatically +python stop.py # Stop the server +python restart.py # Restart the server +python restart.py --port 9000 # Restart on a custom port +``` + +--- + +## 🔌 API Endpoints + +| Method | Endpoint | Description | +|---|---|---| +| `POST` | `/api/upload` | Upload a video file for processing | +| `POST` | `/api/upscale/start` | Start an upscale job with the given configuration | +| `GET` | `/api/upscale/status/{job_id}` | Get the current status and progress of a job | +| `POST` | `/api/upscale/cancel/{job_id}` | Cancel a running or queued job | +| `POST` | `/api/preview/generate` | Generate an upscaled preview of a single frame | +| `GET` | `/api/models` | List all available upscaling models | +| `POST` | `/api/models/upload` | Upload a custom model (`.param` + `.bin`) | +| `GET` | `/api/outputs` | List completed output files | +| `GET` | `/api/download/{filename}` | Download a completed output video | +| `GET` | `/api/diagnostics` | System diagnostics (GPU, Vulkan, disk, dependencies) | +| `WS` | `/ws/progress/{job_id}` | WebSocket stream of real-time job progress updates | + +--- + +## 📁 Project Structure + +``` +video_upscaler/ +├── app/ +│ ├── main.py # FastAPI application & API routes +│ └── upscaler.py # Video processing pipeline +├── static/ +│ ├── index.html # Web dashboard +│ ├── styles.css # UI styles +│ └── app.js # Frontend logic +├── realesrgan-bin/ +│ ├── realesrgan-ncnn-vulkan # Upscaling binary (x86_64 Linux) +│ └── models/ # AI model files (.param + .bin) +├── uploads/ # Uploaded video files (gitignored) +├── outputs/ # Upscaled video files (gitignored) +├── temp/ # Temporary frame data (gitignored) +├── start.py # Start the server +├── stop.py # Stop the server +├── restart.py # Restart the server +├── setup.sh # First-time setup script +├── requirements.txt # Python dependencies +└── README.md +``` + +--- + +## 🔧 Troubleshooting + +### Vulkan not detected + +``` +Error: vkCreateInstance failed +``` + +- Ensure your GPU drivers are up to date. +- Verify Vulkan is working: `vulkaninfo | head -20`. +- Install the Vulkan loader if missing: `sudo apt install libvulkan1 vulkan-tools` (Debian/Ubuntu). + +### Out of VRAM + +``` +Error: vkAllocateMemory failed +``` + +- Lower the **tile size** in the upscale settings (e.g., from `0` to `128` or `64`). +- Close other GPU-intensive applications. +- Use a model with lower memory requirements (e.g., `realesr-animevideov3`). + +### Server won't start + +- Check if the port is already in use: `ss -tlnp | grep 8000`. +- Review the log file: `cat server.log`. +- Ensure the virtual environment is activated or was created by `setup.sh`. + +### FFmpeg errors + +- Confirm `ffmpeg` and `ffprobe` are installed: `ffmpeg -version`. +- Make sure the input video is not corrupted: `ffprobe input.mp4`. +- Check available disk space — upscaling generates large intermediate frame sequences. + +--- + +## 📄 License + +This project uses [Real-ESRGAN](https://github.com/xinntao/Real-ESRGAN) by [xinntao](https://github.com/xinntao), licensed under the [BSD-3-Clause License](https://github.com/xinntao/Real-ESRGAN/blob/master/LICENSE). diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..d5a54e0 --- /dev/null +++ b/app/main.py @@ -0,0 +1,684 @@ +import os +import uuid +import queue +import threading +import asyncio +import subprocess +import urllib.request +import json +from typing import Dict, List, Any +from fastapi import FastAPI, UploadFile, File, Form, BackgroundTasks, HTTPException, WebSocket, WebSocketDisconnect +from fastapi.responses import FileResponse, JSONResponse +from fastapi.staticfiles import StaticFiles +from fastapi.middleware.cors import CORSMiddleware +from pydantic import BaseModel + +import app.upscaler as upscaler + +app = FastAPI(title="AI Video Upscaler Dashboard") + +# CORS middleware for local development +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# In-memory databases +jobs_db: Dict[str, upscaler.UpscaleJob] = {} +ws_connections: Dict[str, List[WebSocket]] = {} +preview_db: Dict[str, Dict[str, str]] = {} # preview_id -> {orig, upscaled} + +# FIFO queue for upscaling jobs to prevent GPU memory overload +job_queue = queue.Queue() +queue_lock = threading.Lock() +current_running_job_id = None + +main_loop = None + +@app.on_event("startup") +def startup_event(): + global main_loop + main_loop = asyncio.get_event_loop() + +global_webhook_url = None + +class WebhookSetupRequest(BaseModel): + url: str + +def send_webhook_notification(url: str, payload: dict): + def post(): + try: + req = urllib.request.Request( + url, + data=json.dumps(payload).encode('utf-8'), + headers={'Content-Type': 'application/json'} + ) + with urllib.request.urlopen(req, timeout=5) as response: + response.read() + except Exception as e: + print(f"Webhook notification failed to {url}: {e}") + threading.Thread(target=post, daemon=True).start() + +# Broadcast updates to websockets and webhooks +def broadcast_progress(job_id: str, data: dict): + job = jobs_db.get(job_id) + if job: + data["is_preview"] = getattr(job, "is_preview", False) + if getattr(job, "is_preview", False): + data["original_preview_file"] = f"original_{job_id}.{getattr(job, 'transcode_format', 'mp4')}" + + if job_id in ws_connections and main_loop is not None: + active_sockets = list(ws_connections[job_id]) + for websocket in active_sockets: + try: + # Schedule the coroutine in the main event loop + asyncio.run_coroutine_threadsafe(websocket.send_json(data), main_loop) + except Exception as e: + print(f"Error sending websocket message: {e}") + + # Process webhooks + job = jobs_db.get(job_id) + webhook_url = None + if job and getattr(job, "webhook_url", None): + webhook_url = job.webhook_url + elif global_webhook_url: + webhook_url = global_webhook_url + + if webhook_url: + payload = { + "job_id": job_id, + "status": data.get("status"), + "progress": data.get("progress"), + "current_frame": data.get("current_frame"), + "total_frames": data.get("total_frames"), + "eta": data.get("eta"), + "error": data.get("error"), + "output_file": data.get("output_file") + } + send_webhook_notification(webhook_url, payload) + +# Sequential queue processor thread +def queue_worker(): + global current_running_job_id + while True: + try: + job_id = job_queue.get() + if job_id is None: + break + + job = jobs_db.get(job_id) + if not job or job.status == "cancelled": + job_queue.task_done() + continue + + with queue_lock: + current_running_job_id = job_id + + print(f"Starting job {job_id}...") + upscaler.run_upscale_pipeline(job, broadcast_progress) + + with queue_lock: + current_running_job_id = None + + job_queue.task_done() + except Exception as e: + print(f"Error in queue worker: {e}") + +# Start the background queue worker thread +worker_thread = threading.Thread(target=queue_worker, daemon=True) +worker_thread.start() + + +class StartUpscaleRequest(BaseModel): + file_id: str + model: str = "realesr-animevideov3" + scale: int = 4 + tile_size: int = 256 + preserve_audio: bool = True + ss: str | None = None + t: str | None = None + gpu_ids: str | None = None + tta: bool = False + unsharp: bool = False + double_fps: bool = False + preserve_subtitles: bool = True + start_sec: float | None = None + end_sec: float | None = None + crf: int = 18 + preset: str = "medium" + denoise: bool = False + sharpen: bool = False + interpolation: bool = False + webhook_url: str | None = None + transcode_format: str = "mp4" + is_preview: bool = False + +class PreviewRequest(BaseModel): + file_id: str + timestamp_sec: float = 1.0 + model: str = "realesr-animevideov3" + scale: int = 4 + tile_size: int = 256 + gpu_ids: str | None = None + + +# Endpoints +@app.post("/api/upload") +async def upload_video(file: UploadFile = File(...)): + """Upload video to workspace directory and parse metadata""" + file_id = str(uuid.uuid4()) + ext = os.path.splitext(file.filename)[1].lower() + if ext not in [".mp4", ".mkv", ".avi", ".mov", ".webm"]: + raise HTTPException(status_code=400, detail="Invalid video format. Supported: .mp4, .mkv, .avi, .mov, .webm") + + save_path = os.path.join(upscaler.UPLOAD_DIR, f"{file_id}{ext}") + + with open(save_path, "wb") as buffer: + content = await file.read() + buffer.write(content) + + info = upscaler.get_video_info(save_path) + if not info: + # cleanup if reading failed + os.remove(save_path) + raise HTTPException(status_code=400, detail="Could not read video file metadata. File may be corrupted.") + + return { + "file_id": file_id, + "filename": file.filename, + "path": save_path, + "metadata": info + } + +@app.post("/api/upscale/start") +def start_upscale(req: StartUpscaleRequest): + """Queue upscaling task""" + # Find uploaded file + file_path = None + exts = [".mp4", ".mkv", ".avi", ".mov", ".webm"] + for ext in exts: + test_path = os.path.join(upscaler.UPLOAD_DIR, f"{req.file_id}{ext}") + if os.path.exists(test_path): + file_path = test_path + break + + if not file_path: + raise HTTPException(status_code=404, detail="Uploaded file not found.") + + job_id = str(uuid.uuid4()) + job = upscaler.UpscaleJob( + job_id=job_id, + video_path=file_path, + model=req.model, + scale=req.scale, + tile_size=req.tile_size, + preserve_audio=req.preserve_audio, + ss=req.ss, + t=req.t, + gpu_ids=req.gpu_ids, + tta=req.tta, + unsharp=req.unsharp, + double_fps=req.double_fps, + preserve_subtitles=req.preserve_subtitles, + start_sec=req.start_sec, + end_sec=req.end_sec, + crf=req.crf, + preset=req.preset, + denoise=req.denoise, + sharpen=req.sharpen, + interpolation=req.interpolation, + webhook_url=req.webhook_url, + transcode_format=req.transcode_format, + is_preview=req.is_preview + ) + + jobs_db[job_id] = job + job_queue.put(job_id) + + # Broadcast initial queued progress + broadcast_progress(job_id, { + "status": "queued", + "progress": 0.0, + "current_frame": 0, + "total_frames": 0, + "eta": "Calculating..." + }) + + return { + "job_id": job_id, + "status": "queued" + } + +@app.get("/api/upscale/status/{job_id}") +def get_status(job_id: str): + """Get status of upscale job""" + job = jobs_db.get(job_id) + if not job: + raise HTTPException(status_code=404, detail="Job not found.") + + return { + "job_id": job.job_id, + "status": job.status, + "progress": job.progress, + "current_frame": job.current_frame, + "total_frames": job.total_frames, + "eta": job.eta, + "error": job.error, + "output_file": os.path.basename(job.output_file) if job.output_file else None, + "is_preview": getattr(job, "is_preview", False), + "original_preview_file": f"original_{job_id}.{getattr(job, 'transcode_format', 'mp4')}" if getattr(job, "is_preview", False) else None + } + +@app.post("/api/upscale/cancel/{job_id}") +def cancel_job(job_id: str): + """Cancel a running or queued job""" + job = jobs_db.get(job_id) + if not job: + raise HTTPException(status_code=404, detail="Job not found.") + + job.cancel() + # Broadcast cancellation status + broadcast_progress(job_id, { + "status": "cancelled", + "progress": job.progress, + "current_frame": job.current_frame, + "total_frames": job.total_frames, + "eta": "N/A" + }) + return {"job_id": job_id, "status": "cancelled"} + +@app.post("/api/preview/generate") +async def generate_preview(req: PreviewRequest): + """Generate high quality upscaled single frame preview""" + file_path = None + exts = [".mp4", ".mkv", ".avi", ".mov", ".webm"] + for ext in exts: + test_path = os.path.join(upscaler.UPLOAD_DIR, f"{req.file_id}{ext}") + if os.path.exists(test_path): + file_path = test_path + break + + if not file_path: + raise HTTPException(status_code=404, detail="Video file not found.") + + preview_id = str(uuid.uuid4()) + preview_temp_dir = os.path.join(upscaler.TEMP_DIR, f"preview_{preview_id}") + os.makedirs(preview_temp_dir, exist_ok=True) + + orig_path = os.path.join(preview_temp_dir, "orig.jpg") + upscaled_path = os.path.join(preview_temp_dir, "upscaled.jpg") + + # Extract frame + extracted = upscaler.extract_single_frame(file_path, req.timestamp_sec, orig_path) + if not extracted: + raise HTTPException(status_code=500, detail="Failed to extract preview frame from video.") + + # Upscale frame + upscaled = upscaler.upscale_image_file(orig_path, upscaled_path, req.model, req.scale, req.tile_size, req.gpu_ids) + if not upscaled: + raise HTTPException(status_code=500, detail="Failed to upscale preview frame.") + + preview_db[preview_id] = { + "orig": orig_path, + "upscaled": upscaled_path + } + + return {"preview_id": preview_id} + +@app.get("/api/preview/original/{preview_id}") +def get_preview_original(preview_id: str): + paths = preview_db.get(preview_id) + if not paths or not os.path.exists(paths["orig"]): + raise HTTPException(status_code=404, detail="Preview frame not found.") + return FileResponse(paths["orig"]) + +@app.get("/api/preview/upscaled/{preview_id}") +def get_preview_upscaled(preview_id: str): + paths = preview_db.get(preview_id) + if not paths or not os.path.exists(paths["upscaled"]): + raise HTTPException(status_code=404, detail="Preview frame not found.") + return FileResponse(paths["upscaled"]) + +@app.get("/api/models") +def get_models(): + """Scan models directory and return list of available models""" + models_dir = os.path.join(upscaler.BASE_DIR, "realesrgan-bin", "models") + if not os.path.exists(models_dir): + return [] + + models = set() + for filename in os.listdir(models_dir): + if filename.endswith(".param"): + name = filename[:-6] # strip '.param' + # Strip scale suffix if present + for suffix in ["-x2", "-x3", "-x4"]: + if name.endswith(suffix): + name = name[:-len(suffix)] + break + models.add(name) + + return sorted(list(models)) + +@app.get("/api/download/{filename}") +def download_file(filename: str): + file_path = os.path.join(upscaler.OUTPUT_DIR, filename) + if not os.path.exists(file_path): + raise HTTPException(status_code=404, detail="File not found.") + return FileResponse(file_path, media_type="application/octet-stream", filename=filename) + +def safe_delete_file(file_path: str): + if file_path and os.path.exists(file_path): + try: + os.remove(file_path) + print(f"Deleted file: {file_path}") + except Exception as e: + print(f"Failed to delete {file_path}: {e}") + +@app.get("/api/jobs") +def list_jobs(): + """List details of all submitted jobs""" + return [ + { + "job_id": job.job_id, + "status": job.status, + "progress": job.progress, + "current_frame": job.current_frame, + "total_frames": job.total_frames, + "eta": job.eta, + "error": job.error, + "model": job.model, + "scale": job.scale, + "output_file": os.path.basename(job.output_file) if job.output_file else None, + "video_path": job.video_path, + "is_preview": getattr(job, "is_preview", False) + } + for job in jobs_db.values() + ] + +@app.delete("/api/jobs/{job_id}") +@app.post("/api/jobs/delete/{job_id}") +def delete_job(job_id: str): + job = jobs_db.get(job_id) + if not job: + raise HTTPException(status_code=404, detail="Job not found.") + + # Safely delete uploaded input file + if job.video_path: + safe_delete_file(job.video_path) + + # Safely delete original preview video if present + for ext in [".mp4", ".mkv", ".avi", ".mov", ".webm"]: + orig_prev_path = os.path.join(upscaler.OUTPUT_DIR, f"original_{job_id}{ext}") + if os.path.exists(orig_prev_path): + safe_delete_file(orig_prev_path) + + # Safely delete upscaled output file + if job.output_file: + safe_delete_file(job.output_file) + + # Clean up any residual temp folder + job_temp_dir = os.path.join(upscaler.TEMP_DIR, job_id) + if os.path.exists(job_temp_dir): + try: + import shutil + shutil.rmtree(job_temp_dir) + except Exception: + pass + + # Delete from in-memory db + if job_id in jobs_db: + del jobs_db[job_id] + + return {"job_id": job_id, "status": "purged"} + +@app.post("/api/jobs/purge-all") +def purge_all_jobs(): + # Purge uploads folder + for f in os.listdir(upscaler.UPLOAD_DIR): + safe_delete_file(os.path.join(upscaler.UPLOAD_DIR, f)) + + # Purge outputs folder + for f in os.listdir(upscaler.OUTPUT_DIR): + safe_delete_file(os.path.join(upscaler.OUTPUT_DIR, f)) + + # Purge temp folder + for f in os.listdir(upscaler.TEMP_DIR): + path = os.path.join(upscaler.TEMP_DIR, f) + try: + if os.path.isdir(path): + import shutil + shutil.rmtree(path) + else: + os.remove(path) + except Exception: + pass + + # Reset in-memory database + jobs_db.clear() + + return {"status": "all purged"} + +# Websocket endpoint for real-time progress updates +@app.websocket("/ws/progress/{job_id}") +async def websocket_progress(websocket: WebSocket, job_id: str): + await websocket.accept() + if job_id not in ws_connections: + ws_connections[job_id] = [] + ws_connections[job_id].append(websocket) + + # Send current state immediately + job = jobs_db.get(job_id) + if job: + await websocket.send_json({ + "status": job.status, + "progress": job.progress, + "current_frame": job.current_frame, + "total_frames": job.total_frames, + "eta": job.eta, + "error": job.error, + "output_file": os.path.basename(job.output_file) if job.output_file else None + }) + + try: + while True: + # Just keep the connection alive + await websocket.receive_text() + except WebSocketDisconnect: + if job_id in ws_connections: + ws_connections[job_id].remove(websocket) + if not ws_connections[job_id]: + del ws_connections[job_id] + +# Clean up previews on exit +@app.on_event("shutdown") +def cleanup_previews(): + for preview_id, paths in preview_db.items(): + try: + parent_dir = os.path.dirname(paths["orig"]) + if os.path.exists(parent_dir): + import shutil + shutil.rmtree(parent_dir) + except Exception: + pass + +# System Diagnostics Endpoint +@app.get("/api/diagnostics") +def get_diagnostics(): + # RAM Diagnostics + ram = {"total": 0, "available": 0, "used": 0, "percent": 0.0} + try: + if os.path.exists('/proc/meminfo'): + mem_info = {} + with open('/proc/meminfo', 'r') as f: + for line in f: + parts = line.split(':') + if len(parts) == 2: + name = parts[0].strip() + val = parts[1].replace('kB', '').strip() + mem_info[name] = int(val) + total = mem_info.get('MemTotal', 0) * 1024 + free = mem_info.get('MemFree', 0) * 1024 + available = mem_info.get('MemAvailable', total - free) * 1024 + used = total - available + percent = round((used / total) * 100, 1) if total > 0 else 0.0 + ram = { + "total": total, + "available": available, + "used": used, + "percent": percent + } + except Exception as e: + print(f"Error getting RAM diagnostics: {e}") + + # CPU Diagnostics + cpu = {"count": os.cpu_count(), "load_avg": [], "percent": 0.0} + try: + load_1, load_5, load_15 = os.getloadavg() + cpu["load_avg"] = [load_1, load_5, load_15] + cpu["percent"] = min(100.0, round((load_1 / cpu["count"]) * 100, 1)) if cpu["count"] else 0.0 + except Exception as e: + print(f"Error getting CPU diagnostics: {e}") + + # GPU Diagnostics + gpu = {"available": False, "gpus": []} + try: + cmd = [ + "nvidia-smi", + "--query-gpu=utilization.gpu,utilization.memory,memory.total,memory.free,memory.used,name,temperature.gpu", + "--format=csv,noheader,nounits" + ] + res = subprocess.run(cmd, capture_output=True, text=True, check=True) + lines = res.stdout.strip().split('\n') + gpu_list = [] + for line in lines: + if not line.strip(): + continue + parts = [p.strip() for p in line.split(',')] + if len(parts) >= 7: + gpu_list.append({ + "name": parts[5], + "gpu_utilization_percent": float(parts[0]), + "memory_utilization_percent": float(parts[1]), + "memory_total_mb": float(parts[2]), + "memory_free_mb": float(parts[3]), + "memory_used_mb": float(parts[4]), + "temperature_c": float(parts[6]) + }) + if gpu_list: + gpu["available"] = True + gpu["gpus"] = gpu_list + except Exception as e: + gpu["error"] = str(e) + + return { + "ram": ram, + "cpu": cpu, + "gpu": gpu + } + +# Outputs Gallery Endpoints +@app.get("/api/outputs") +def list_outputs(): + output_dir = upscaler.OUTPUT_DIR + if not os.path.exists(output_dir): + return [] + + files = [] + for filename in os.listdir(output_dir): + if filename.startswith("original_"): + continue + file_path = os.path.join(output_dir, filename) + if os.path.isfile(file_path): + stat = os.stat(file_path) + files.append({ + "filename": filename, + "size": stat.st_size, + "modified": stat.st_mtime, + "url": f"/api/download/{filename}" + }) + files.sort(key=lambda x: x["modified"], reverse=True) + return files + +@app.delete("/api/outputs/delete/{filename}") +@app.post("/api/outputs/delete/{filename}") +def delete_output(filename: str): + file_path = os.path.join(upscaler.OUTPUT_DIR, filename) + resolved_path = os.path.abspath(file_path) + if not resolved_path.startswith(os.path.abspath(upscaler.OUTPUT_DIR)): + raise HTTPException(status_code=403, detail="Access denied.") + + if not os.path.exists(file_path): + raise HTTPException(status_code=404, detail="File not found.") + + try: + os.remove(file_path) + return {"filename": filename, "status": "deleted"} + except Exception as e: + raise HTTPException(status_code=500, detail=f"Failed to delete file: {e}") + +# Custom Model Uploading Endpoint +@app.post("/api/models/upload") +async def upload_model( + param_file: UploadFile = File(None), + bin_file: UploadFile = File(None), + files: List[UploadFile] = File(None) +): + models_dir = os.path.join(upscaler.BASE_DIR, "realesrgan-bin", "models") + os.makedirs(models_dir, exist_ok=True) + + uploaded_files = [] + all_files = [] + if files: + all_files.extend(files) + if param_file: + all_files.append(param_file) + if bin_file: + all_files.append(bin_file) + + if not all_files: + raise HTTPException(status_code=400, detail="No files uploaded. Please upload .param or .bin files.") + + for f in all_files: + filename = f.filename + ext = os.path.splitext(filename)[1].lower() + if ext not in [".param", ".bin"]: + raise HTTPException( + status_code=400, + detail=f"Invalid file extension: {ext}. Only .param and .bin files are allowed for models." + ) + + safe_filename = os.path.basename(filename) + save_path = os.path.join(models_dir, safe_filename) + + with open(save_path, "wb") as buffer: + content = await f.read() + buffer.write(content) + uploaded_files.append(safe_filename) + + return { + "status": "success", + "uploaded": uploaded_files + } + +# Webhook Setup/Retrieval Endpoints +@app.post("/api/webhook/setup") +def setup_webhook(req: WebhookSetupRequest): + global global_webhook_url + global_webhook_url = req.url + return {"status": "success", "webhook_url": global_webhook_url} + +@app.get("/api/uploads/{filename}") +def get_upload_file(filename: str): + file_path = os.path.join(upscaler.UPLOAD_DIR, filename) + resolved_path = os.path.abspath(file_path) + if not resolved_path.startswith(os.path.abspath(upscaler.UPLOAD_DIR)): + raise HTTPException(status_code=403, detail="Access denied.") + if not os.path.exists(file_path): + raise HTTPException(status_code=404, detail="File not found.") + return FileResponse(file_path) + +# Mount static folder +app.mount("/", StaticFiles(directory=os.path.join(upscaler.BASE_DIR, "static"), html=True), name="static") diff --git a/app/upscaler.py b/app/upscaler.py new file mode 100644 index 0000000..23c8b2a --- /dev/null +++ b/app/upscaler.py @@ -0,0 +1,519 @@ +import os +import subprocess +import json +import shutil +import time +import threading +from typing import Dict, Any, Callable + +# Paths config +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +BIN_PATH = os.path.join(BASE_DIR, "realesrgan-bin", "realesrgan-ncnn-vulkan") +UPLOAD_DIR = os.path.join(BASE_DIR, "uploads") +OUTPUT_DIR = os.path.join(BASE_DIR, "outputs") +TEMP_DIR = os.path.join(BASE_DIR, "temp") + +# Ensure directories exist +for d in [UPLOAD_DIR, OUTPUT_DIR, TEMP_DIR]: + os.makedirs(d, exist_ok=True) + +class UpscaleJob: + def __init__(self, job_id: str, video_path: str, model: str, scale: int, tile_size: int, preserve_audio: bool, + ss: str = None, t: str = None, gpu_ids: str = None, tta: bool = False, + unsharp: bool = False, double_fps: bool = False, preserve_subtitles: bool = True, + start_sec: float = None, end_sec: float = None, crf: int = 18, preset: str = "medium", + denoise: bool = False, sharpen: bool = False, interpolation: bool = False, + webhook_url: str = None, transcode_format: str = "mp4", is_preview: bool = False): + self.job_id = job_id + self.video_path = video_path + self.model = model + self.scale = scale + self.tile_size = tile_size + self.preserve_audio = preserve_audio + + # Trim mapping + if ss is not None: + self.ss = ss + elif start_sec is not None: + self.ss = str(start_sec) + else: + self.ss = None + + if t is not None: + self.t = t + elif end_sec is not None: + start = float(self.ss) if self.ss is not None else 0.0 + self.t = str(max(0.0, end_sec - start)) + else: + self.t = None + + self.gpu_ids = gpu_ids + self.tta = tta + self.unsharp = unsharp + self.double_fps = double_fps + self.preserve_subtitles = preserve_subtitles + self.start_sec = start_sec + self.end_sec = end_sec + self.crf = crf + self.preset = preset + self.denoise = denoise + self.sharpen = sharpen + self.interpolation = interpolation + self.webhook_url = webhook_url + self.transcode_format = transcode_format + self.is_preview = is_preview + self.original_preview_file = None + + self.status = "pending" + self.progress = 0.0 + self.current_frame = 0 + self.total_frames = 0 + self.eta = "Calculating..." + self.error = None + self.start_time = None + self.output_file = None + + # Track processes to allow cancellation + self._processes = [] + self._is_cancelled = False + self._lock = threading.Lock() + + def update_status(self, status: str, progress: float = None, current_frame: int = None, eta: str = None, error: str = None): + with self._lock: + self.status = status + if progress is not None: + self.progress = round(progress, 2) + if current_frame is not None: + self.current_frame = current_frame + if eta is not None: + self.eta = eta + if error is not None: + self.error = error + + def cancel(self): + with self._lock: + self._is_cancelled = True + self.status = "cancelled" + self.eta = "N/A" + for p in self._processes: + try: + p.terminate() + p.wait(timeout=2) + except Exception: + try: + p.kill() + except Exception: + pass + self._processes.clear() + + def run_command(self, cmd: list, shell=False) -> subprocess.Popen: + with self._lock: + if self._is_cancelled: + raise InterruptedError("Job was cancelled") + + p = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + shell=shell + ) + self._processes.append(p) + return p + + def cleanup_process(self, p: subprocess.Popen): + with self._lock: + if p in self._processes: + self._processes.remove(p) + +def get_video_info(video_path: str) -> dict: + """Extract metadata using ffprobe""" + cmd = [ + "ffprobe", + "-v", "error", + "-select_streams", "v:0", + "-show_entries", "stream=avg_frame_rate,duration,width,height,codec_name,nb_frames", + "-of", "json", + video_path + ] + try: + result = subprocess.run(cmd, capture_output=True, text=True, check=True) + data = json.loads(result.stdout) + if not data.get("streams"): + return {} + + stream = data["streams"][0] + + # Calculate FPS + fps_str = stream.get("avg_frame_rate", "30/1") + if "/" in fps_str: + num, den = map(float, fps_str.split("/")) + fps = num / den if den != 0 else 30.0 + else: + fps = float(fps_str) if fps_str else 30.0 + + # Get total frames + nb_frames = stream.get("nb_frames") + if nb_frames and nb_frames.isdigit(): + total_frames = int(nb_frames) + else: + duration = float(stream.get("duration", 0)) + total_frames = int(duration * fps) + + return { + "width": int(stream.get("width", 0)), + "height": int(stream.get("height", 0)), + "fps": round(fps, 3), + "duration": round(float(stream.get("duration", 0)), 2), + "codec": stream.get("codec_name", "unknown"), + "total_frames": total_frames + } + except Exception as e: + print(f"Error reading video info: {e}") + return {} + +def extract_single_frame(video_path: str, timestamp_sec: float, output_path: str) -> bool: + """Extract a single frame at timestamp for preview""" + cmd = [ + "ffmpeg", "-y", + "-ss", str(timestamp_sec), + "-i", video_path, + "-vframes", "1", + "-f", "image2", + output_path + ] + try: + subprocess.run(cmd, capture_output=True, check=True) + return os.path.exists(output_path) + except Exception as e: + print(f"Error extracting single frame: {e}") + return False + +def upscale_image_file(input_path: str, output_path: str, model: str, scale: int, tile_size: int, gpu_ids: str = None) -> bool: + """Run Real-ESRGAN on a single image file""" + cmd = [ + BIN_PATH, + "-i", input_path, + "-o", output_path, + "-n", model, + "-s", str(scale), + "-t", str(tile_size) + ] + if gpu_ids is not None: + cmd.extend(["-g", str(gpu_ids)]) + try: + subprocess.run(cmd, capture_output=True, check=True) + return os.path.exists(output_path) + except Exception as e: + print(f"Error upscaling single image: {e}") + return False + +def run_upscale_pipeline(job: UpscaleJob, on_progress_update: Callable[[str, Dict[str, Any]], None]): + job.start_time = time.time() + job.update_status("analyzing", progress=5) + + # Get video info + info = get_video_info(job.video_path) + if not info: + job.update_status("failed", error="Could not read video metadata.") + on_progress_update(job.job_id, {"status": "failed", "error": "Could not read video metadata"}) + return + + job.total_frames = info["total_frames"] + fps = info["fps"] + + # Create job temp directories + job_temp_dir = os.path.join(TEMP_DIR, job.job_id) + input_frames_dir = os.path.join(job_temp_dir, "input_frames") + output_frames_dir = os.path.join(job_temp_dir, "output_frames") + + os.makedirs(input_frames_dir, exist_ok=True) + os.makedirs(output_frames_dir, exist_ok=True) + + try: + # If preview, extract the original 5s clip first + transcode_fmt = getattr(job, "transcode_format", "mp4") + if getattr(job, "is_preview", False): + orig_preview_filename = f"original_{job.job_id}.{transcode_fmt}" + orig_preview_filepath = os.path.join(OUTPUT_DIR, orig_preview_filename) + job.original_preview_file = orig_preview_filepath + + cut_cmd = ["ffmpeg", "-y"] + if job.ss is not None: + cut_cmd.extend(["-ss", str(job.ss)]) + if job.t is not None: + cut_cmd.extend(["-t", str(job.t)]) + cut_cmd.extend([ + "-i", job.video_path, + "-map", "0:v:0", + "-map", "0:a:0?", + "-c:v", "libx264", + "-c:a", "aac", + orig_preview_filepath + ]) + try: + subprocess.run(cut_cmd, capture_output=True, check=True) + except Exception as cut_err: + print(f"Error cutting original preview video: {cut_err}") + + # Step 1: Extract Frames + job.update_status("extracting", progress=10) + on_progress_update(job.job_id, {"status": "extracting", "progress": 10}) + + # High quality JPG frames to balance disk usage and speed + extract_cmd = ["ffmpeg", "-y"] + if job.ss is not None: + extract_cmd.extend(["-ss", str(job.ss)]) + if job.t is not None: + extract_cmd.extend(["-t", str(job.t)]) + extract_cmd.extend(["-i", job.video_path]) + + # Apply unsharp pre-filter if enabled + if getattr(job, "unsharp", False): + extract_cmd.extend(["-vf", "unsharp"]) + + extract_cmd.extend([ + "-q:v", "2", + os.path.join(input_frames_dir, "frame_%08d.jpg") + ]) + + p_extract = job.run_command(extract_cmd) + stdout, stderr = p_extract.communicate() + job.cleanup_process(p_extract) + + if p_extract.returncode != 0: + raise RuntimeError(f"FFmpeg frame extraction failed: {stderr}") + + # Count actual frames extracted + extracted_files = sorted([f for f in os.listdir(input_frames_dir) if f.startswith("frame_")]) + actual_total = len(extracted_files) + if actual_total == 0: + raise RuntimeError("No frames extracted from video") + + job.total_frames = actual_total + + # Step 2: Upscale Frames + job.update_status("upscaling", progress=20, current_frame=0) + on_progress_update(job.job_id, {"status": "upscaling", "progress": 20, "current_frame": 0, "total_frames": actual_total}) + + current_tile_size = job.tile_size + while True: + # Launch Real-ESRGAN on directory + upscale_cmd = [ + BIN_PATH, + "-i", input_frames_dir, + "-o", output_frames_dir, + "-n", job.model, + "-s", str(job.scale), + "-t", str(current_tile_size), + "-f", "jpg" + ] + if getattr(job, "gpu_ids", None) is not None: + upscale_cmd.extend(["-g", str(job.gpu_ids)]) + if getattr(job, "tta", False): + upscale_cmd.append("-x") + + upscale_start_time = time.time() + p_upscale = job.run_command(upscale_cmd) + + # Monitor thread for output files + while p_upscale.poll() is None: + if job._is_cancelled: + return + + processed_files = len(os.listdir(output_frames_dir)) + progress_pct = 20.0 + (float(processed_files) / actual_total) * 60.0 # upscaling is 20% to 80% + + # Estimate ETA + elapsed = time.time() - upscale_start_time + if processed_files > 0: + sec_per_frame = elapsed / processed_files + rem_frames = actual_total - processed_files + eta_sec = rem_frames * sec_per_frame + + # Format ETA + if eta_sec > 60: + eta_str = f"{int(eta_sec // 60)}m {int(eta_sec % 60)}s" + else: + eta_str = f"{int(eta_sec)}s" + else: + eta_str = "Calculating..." + + job.update_status("upscaling", progress=progress_pct, current_frame=processed_files, eta=eta_str) + on_progress_update(job.job_id, { + "status": "upscaling", + "progress": progress_pct, + "current_frame": processed_files, + "total_frames": actual_total, + "eta": eta_str + }) + time.sleep(0.5) + + stdout, stderr = p_upscale.communicate() + job.cleanup_process(p_upscale) + + if job._is_cancelled: + return + + if p_upscale.returncode != 0: + err_msg = (stdout or "") + "\n" + (stderr or "") + is_alloc_error = any(x in err_msg.lower() for x in ["vkallocatememory", "out of memory", "allocation", "vram", "failed to allocate"]) + + if is_alloc_error: + if current_tile_size <= 0: + next_tile_size = 256 + else: + next_tile_size = current_tile_size // 2 + + if next_tile_size >= 32: + print(f"Job {job.job_id}: Real-ESRGAN failed with VRAM allocation error. Retrying with tile size halved from {current_tile_size} to {next_tile_size}.") + current_tile_size = next_tile_size + # Clean up output frames directory before retrying + for filename in os.listdir(output_frames_dir): + file_path = os.path.join(output_frames_dir, filename) + try: + if os.path.isfile(file_path) or os.path.islink(file_path): + os.unlink(file_path) + elif os.path.isdir(file_path): + shutil.rmtree(file_path) + except Exception as cleanup_err: + print(f"Error cleaning file {file_path}: {cleanup_err}") + continue + + raise RuntimeError(f"Real-ESRGAN failed with exit code {p_upscale.returncode}: {err_msg}") + else: + break + + # Final validation of upscale output + processed_files = len(os.listdir(output_frames_dir)) + job.update_status("upscaling", progress=80.0, current_frame=processed_files) + + # Step 3: Reassemble video + job.update_status("assembling", progress=85.0) + on_progress_update(job.job_id, {"status": "assembling", "progress": 85.0}) + + transcode_fmt = getattr(job, "transcode_format", "mp4") + out_filename = f"upscaled_{job.job_id}.{transcode_fmt}" + out_filepath = os.path.join(OUTPUT_DIR, out_filename) + job.output_file = out_filepath + + # Choose codecs based on format + vcodec = "libx264" + acodec = "copy" + if transcode_fmt == "webm": + vcodec = "libvpx-vp9" + acodec = "libvorbis" + + # Construct ffmpeg reassembly command + assemble_cmd = [ + "ffmpeg", "-y", + "-framerate", str(fps), + "-i", os.path.join(output_frames_dir, "frame_%08d.jpg") + ] + + # We need the original video as the second input (index 1) if we preserve audio or subtitles + need_orig_input = job.preserve_audio or getattr(job, "preserve_subtitles", True) + if need_orig_input: + orig_input_cmd = [] + if getattr(job, "ss", None) is not None: + orig_input_cmd.extend(["-ss", str(job.ss)]) + if getattr(job, "t", None) is not None: + orig_input_cmd.extend(["-t", str(job.t)]) + orig_input_cmd.extend(["-i", job.video_path]) + assemble_cmd.extend(orig_input_cmd) + + assemble_cmd.extend(["-map", "0:v:0"]) + + if job.preserve_audio: + assemble_cmd.extend([ + "-map", "1:a:0?", + "-c:a", acodec + ]) + + if getattr(job, "preserve_subtitles", True): + assemble_cmd.extend([ + "-map", "1:s?", + "-c:s", "mov_text" + ]) + + # Apply filters + vf_filters = [] + if getattr(job, "denoise", False): + vf_filters.append("hqdn3d") + if getattr(job, "sharpen", False) or getattr(job, "unsharp", False): + vf_filters.append("unsharp=3:3:0.5:3:3:0.5") + if getattr(job, "interpolation", False) or getattr(job, "double_fps", False): + target_fps = fps * 2 if getattr(job, "double_fps", False) else 60 + if target_fps < fps: + target_fps = fps + vf_filters.append(f"minterpolate=fps={target_fps}") + + if vf_filters: + assemble_cmd.extend(["-vf", ",".join(vf_filters)]) + + assemble_cmd.extend([ + "-c:v", vcodec, + "-pix_fmt", "yuv420p", + "-crf", str(getattr(job, "crf", 18)), + "-preset", getattr(job, "preset", "medium"), + out_filepath + ]) + + p_assemble = job.run_command(assemble_cmd) + stdout, stderr = p_assemble.communicate() + job.cleanup_process(p_assemble) + + if p_assemble.returncode != 0: + raise RuntimeError(f"FFmpeg video assembly failed: {stderr}") + + # Step 4: Complete + job.update_status("completed", progress=100.0, eta="Done") + on_progress_update(job.job_id, { + "status": "completed", + "progress": 100.0, + "eta": "Done", + "output_file": out_filename + }) + + except Exception as e: + import traceback + traceback.print_exc() + if not job._is_cancelled: + job.update_status("failed", error=str(e)) + on_progress_update(job.job_id, {"status": "failed", "error": str(e)}) + finally: + # Clean up temp frames to save space + try: + if os.path.exists(job_temp_dir): + shutil.rmtree(job_temp_dir) + except Exception as cleanup_err: + print(f"Error during temp cleanup: {cleanup_err}") + + # Trigger webhook if URL is provided + if getattr(job, "webhook_url", None): + def trigger_webhook_task(): + import urllib.request + import json + try: + payload = { + "job_id": job.job_id, + "status": job.status, + "progress": job.progress, + "error": job.error, + "output_file": os.path.basename(job.output_file) if job.output_file else None, + "model": job.model, + "scale": job.scale, + "duration": round(time.time() - job.start_time, 2) if job.start_time else 0 + } + req = urllib.request.Request( + job.webhook_url, + data=json.dumps(payload).encode('utf-8'), + headers={'Content-Type': 'application/json'}, + method='POST' + ) + with urllib.request.urlopen(req, timeout=5) as response: + pass + except Exception as ex: + print(f"Error triggering webhook: {ex}") + + threading.Thread(target=trigger_webhook_task, daemon=True).start() diff --git a/realesrgan-bin/README_ubuntu.md b/realesrgan-bin/README_ubuntu.md new file mode 100644 index 0000000..fa294e7 --- /dev/null +++ b/realesrgan-bin/README_ubuntu.md @@ -0,0 +1,45 @@ +# RealESRGAN + +We have provided the following models: + +1. realesr-animevideov3 (default) +2. realesrgan-x4plus +3. realesrgan-x4plus-anime + +Command: + +You may need to change file mode before running. + +chmod u+x realesrgan-ncnn-vulkan + +1. ./realesrgan-ncnn-vulkan -i input.jpg -o output.png +2. ./realesrgan-ncnn-vulkan -i input.jpg -o output.png -n realesr-animevideov3 +3. ./realesrgan-ncnn-vulkan -i input_folder -o outputfolder -n realesr-animevideov3 -s 2 -f jpg +4. ./realesrgan-ncnn-vulkan -i input_folder -o outputfolder -n realesr-animevideov3 -s 4 -f jpg + +Commands for enhancing anime videos: + +1. Use ffmpeg to extract frames from a video (Remember to create the folder `tmp_frames` ahead) + + ffmpeg -i onepiece_demo.mp4 -qscale:v 1 -qmin 1 -qmax 1 -vsync 0 tmp_frames/frame%08d.jpg + +2. Inference with Real-ESRGAN executable file (Remember to create the folder `out_frames` ahead) + + ./realesrgan-ncnn-vulkan -i tmp_frames -o out_frames -n realesr-animevideov3 -s 2 -f jpg + +3. Merge the enhanced frames back into a video + + ffmpeg -i out_frames/frame%08d.jpg -i onepiece_demo.mp4 -map 0:v:0 -map 1:a:0 -c:a copy -c:v libx264 -r 23.98 -pix_fmt yuv420p output_w_audio.mp4 + +------------------------ + +GitHub: https://github.com/xinntao/Real-ESRGAN/ +Paper: https://arxiv.org/abs/2107.10833 + +------------------------ + +This executable file is **portable** and includes all the binaries and models required. No CUDA or PyTorch environment is needed. + +Note that it may introduce block inconsistency (and also generate slightly different results from the PyTorch implementation), because this executable file first crops the input image into several tiles, and then processes them separately, finally stitches together. + +This executable file is based on the wonderful [Tencent/ncnn](https://github.com/Tencent/ncnn) and [realsr-ncnn-vulkan](https://github.com/nihui/realsr-ncnn-vulkan) by [nihui](https://github.com/nihui). diff --git a/realesrgan-bin/input.jpg b/realesrgan-bin/input.jpg new file mode 100644 index 0000000..6186892 Binary files /dev/null and b/realesrgan-bin/input.jpg differ diff --git a/realesrgan-bin/input2.jpg b/realesrgan-bin/input2.jpg new file mode 100644 index 0000000..b4d9c90 Binary files /dev/null and b/realesrgan-bin/input2.jpg differ diff --git a/realesrgan-bin/models/realesr-animevideov3-x2.bin b/realesrgan-bin/models/realesr-animevideov3-x2.bin new file mode 100644 index 0000000..2069105 Binary files /dev/null and b/realesrgan-bin/models/realesr-animevideov3-x2.bin differ diff --git a/realesrgan-bin/models/realesr-animevideov3-x2.param b/realesrgan-bin/models/realesr-animevideov3-x2.param new file mode 100644 index 0000000..42e7748 --- /dev/null +++ b/realesrgan-bin/models/realesr-animevideov3-x2.param @@ -0,0 +1,43 @@ +7767517 +41 42 +Input input.1 0 1 data +Split splitncnn_input0 1 2 data input.1_splitncnn_0 input.1_splitncnn_1 +Convolution Conv_0 1 1 input.1_splitncnn_1 54 0=64 1=3 4=1 5=1 6=1728 +PReLU PRelu_1 1 1 54 56 0=64 +Convolution Conv_2 1 1 56 57 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_3 1 1 57 59 0=64 +Convolution Conv_4 1 1 59 60 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_5 1 1 60 62 0=64 +Convolution Conv_6 1 1 62 63 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_7 1 1 63 65 0=64 +Convolution Conv_8 1 1 65 66 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_9 1 1 66 68 0=64 +Convolution Conv_10 1 1 68 69 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_11 1 1 69 71 0=64 +Convolution Conv_12 1 1 71 72 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_13 1 1 72 74 0=64 +Convolution Conv_14 1 1 74 75 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_15 1 1 75 77 0=64 +Convolution Conv_16 1 1 77 78 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_17 1 1 78 80 0=64 +Convolution Conv_18 1 1 80 81 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_19 1 1 81 83 0=64 +Convolution Conv_20 1 1 83 84 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_21 1 1 84 86 0=64 +Convolution Conv_22 1 1 86 87 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_23 1 1 87 89 0=64 +Convolution Conv_24 1 1 89 90 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_25 1 1 90 92 0=64 +Convolution Conv_26 1 1 92 93 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_27 1 1 93 95 0=64 +Convolution Conv_28 1 1 95 96 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_29 1 1 96 98 0=64 +Convolution Conv_30 1 1 98 99 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_31 1 1 99 101 0=64 +Convolution Conv_32 1 1 101 102 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_33 1 1 102 104 0=64 +Convolution Conv_34 1 1 104 105 0=48 1=3 4=1 5=1 6=27648 +PixelShuffle DepthToSpace_35 1 1 105 106 0=4 +Interp Resize_37 1 1 input.1_splitncnn_0 111 0=1 1=4.000000e+00 2=4.000000e+00 +BinaryOp Add_38 2 1 106 111 112 +Interp Resize_40 1 1 112 output 0=3 1=5.000000e-01 2=5.000000e-01 diff --git a/realesrgan-bin/models/realesr-animevideov3-x3.bin b/realesrgan-bin/models/realesr-animevideov3-x3.bin new file mode 100644 index 0000000..2069105 Binary files /dev/null and b/realesrgan-bin/models/realesr-animevideov3-x3.bin differ diff --git a/realesrgan-bin/models/realesr-animevideov3-x3.param b/realesrgan-bin/models/realesr-animevideov3-x3.param new file mode 100644 index 0000000..bf47185 --- /dev/null +++ b/realesrgan-bin/models/realesr-animevideov3-x3.param @@ -0,0 +1,43 @@ +7767517 +41 42 +Input input.1 0 1 data +Split splitncnn_input0 1 2 data input.1_splitncnn_0 input.1_splitncnn_1 +Convolution Conv_0 1 1 input.1_splitncnn_1 54 0=64 1=3 4=1 5=1 6=1728 +PReLU PRelu_1 1 1 54 56 0=64 +Convolution Conv_2 1 1 56 57 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_3 1 1 57 59 0=64 +Convolution Conv_4 1 1 59 60 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_5 1 1 60 62 0=64 +Convolution Conv_6 1 1 62 63 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_7 1 1 63 65 0=64 +Convolution Conv_8 1 1 65 66 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_9 1 1 66 68 0=64 +Convolution Conv_10 1 1 68 69 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_11 1 1 69 71 0=64 +Convolution Conv_12 1 1 71 72 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_13 1 1 72 74 0=64 +Convolution Conv_14 1 1 74 75 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_15 1 1 75 77 0=64 +Convolution Conv_16 1 1 77 78 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_17 1 1 78 80 0=64 +Convolution Conv_18 1 1 80 81 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_19 1 1 81 83 0=64 +Convolution Conv_20 1 1 83 84 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_21 1 1 84 86 0=64 +Convolution Conv_22 1 1 86 87 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_23 1 1 87 89 0=64 +Convolution Conv_24 1 1 89 90 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_25 1 1 90 92 0=64 +Convolution Conv_26 1 1 92 93 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_27 1 1 93 95 0=64 +Convolution Conv_28 1 1 95 96 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_29 1 1 96 98 0=64 +Convolution Conv_30 1 1 98 99 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_31 1 1 99 101 0=64 +Convolution Conv_32 1 1 101 102 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_33 1 1 102 104 0=64 +Convolution Conv_34 1 1 104 105 0=48 1=3 4=1 5=1 6=27648 +PixelShuffle DepthToSpace_35 1 1 105 106 0=4 +Interp Resize_37 1 1 input.1_splitncnn_0 111 0=1 1=4.000000e+00 2=4.000000e+00 +BinaryOp Add_38 2 1 106 111 112 +Interp Resize_40 1 1 112 output 0=3 1=7.500000e-01 2=7.500000e-01 diff --git a/realesrgan-bin/models/realesr-animevideov3-x4.bin b/realesrgan-bin/models/realesr-animevideov3-x4.bin new file mode 100644 index 0000000..2069105 Binary files /dev/null and b/realesrgan-bin/models/realesr-animevideov3-x4.bin differ diff --git a/realesrgan-bin/models/realesr-animevideov3-x4.param b/realesrgan-bin/models/realesr-animevideov3-x4.param new file mode 100644 index 0000000..5b922cc --- /dev/null +++ b/realesrgan-bin/models/realesr-animevideov3-x4.param @@ -0,0 +1,42 @@ +7767517 +40 41 +Input input.1 0 1 data +Split splitncnn_input0 1 2 data input.1_splitncnn_0 input.1_splitncnn_1 +Convolution Conv_0 1 1 input.1_splitncnn_1 54 0=64 1=3 4=1 5=1 6=1728 +PReLU PRelu_1 1 1 54 56 0=64 +Convolution Conv_2 1 1 56 57 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_3 1 1 57 59 0=64 +Convolution Conv_4 1 1 59 60 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_5 1 1 60 62 0=64 +Convolution Conv_6 1 1 62 63 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_7 1 1 63 65 0=64 +Convolution Conv_8 1 1 65 66 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_9 1 1 66 68 0=64 +Convolution Conv_10 1 1 68 69 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_11 1 1 69 71 0=64 +Convolution Conv_12 1 1 71 72 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_13 1 1 72 74 0=64 +Convolution Conv_14 1 1 74 75 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_15 1 1 75 77 0=64 +Convolution Conv_16 1 1 77 78 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_17 1 1 78 80 0=64 +Convolution Conv_18 1 1 80 81 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_19 1 1 81 83 0=64 +Convolution Conv_20 1 1 83 84 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_21 1 1 84 86 0=64 +Convolution Conv_22 1 1 86 87 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_23 1 1 87 89 0=64 +Convolution Conv_24 1 1 89 90 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_25 1 1 90 92 0=64 +Convolution Conv_26 1 1 92 93 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_27 1 1 93 95 0=64 +Convolution Conv_28 1 1 95 96 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_29 1 1 96 98 0=64 +Convolution Conv_30 1 1 98 99 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_31 1 1 99 101 0=64 +Convolution Conv_32 1 1 101 102 0=64 1=3 4=1 5=1 6=36864 +PReLU PRelu_33 1 1 102 104 0=64 +Convolution Conv_34 1 1 104 105 0=48 1=3 4=1 5=1 6=27648 +PixelShuffle DepthToSpace_35 1 1 105 106 0=4 +Interp Resize_37 1 1 input.1_splitncnn_0 111 0=1 1=4.000000e+00 2=4.000000e+00 +BinaryOp Add_38 2 1 106 111 output diff --git a/realesrgan-bin/models/realesrgan-x4plus-anime.bin b/realesrgan-bin/models/realesrgan-x4plus-anime.bin new file mode 100644 index 0000000..95201b7 Binary files /dev/null and b/realesrgan-bin/models/realesrgan-x4plus-anime.bin differ diff --git a/realesrgan-bin/models/realesrgan-x4plus-anime.param b/realesrgan-bin/models/realesrgan-x4plus-anime.param new file mode 100644 index 0000000..6c98f9a --- /dev/null +++ b/realesrgan-bin/models/realesrgan-x4plus-anime.param @@ -0,0 +1,270 @@ +7767517 +268 473 +Input input.1 0 1 data +Convolution Conv_0 1 1 data 193 0=64 1=3 4=1 5=1 6=1728 +Split splitncnn_0 1 8 193 193_splitncnn_0 193_splitncnn_1 193_splitncnn_2 193_splitncnn_3 193_splitncnn_4 193_splitncnn_5 193_splitncnn_6 193_splitncnn_7 +Convolution Conv_1 1 1 193_splitncnn_7 195 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_1 1 4 195 195_splitncnn_0 195_splitncnn_1 195_splitncnn_2 195_splitncnn_3 +Concat Concat_3 2 1 193_splitncnn_6 195_splitncnn_3 196 +Convolution Conv_4 1 1 196 198 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_2 1 3 198 198_splitncnn_0 198_splitncnn_1 198_splitncnn_2 +Concat Concat_6 3 1 193_splitncnn_5 195_splitncnn_2 198_splitncnn_2 199 +Convolution Conv_7 1 1 199 201 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_3 1 2 201 201_splitncnn_0 201_splitncnn_1 +Concat Concat_9 4 1 193_splitncnn_4 195_splitncnn_1 198_splitncnn_1 201_splitncnn_1 202 +Convolution Conv_10 1 1 202 204 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_12 5 1 193_splitncnn_3 195_splitncnn_0 198_splitncnn_0 201_splitncnn_0 204 205 +Convolution Conv_13 1 1 205 206 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_16 2 1 206 193_splitncnn_2 209 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_4 1 6 209 209_splitncnn_0 209_splitncnn_1 209_splitncnn_2 209_splitncnn_3 209_splitncnn_4 209_splitncnn_5 +Convolution Conv_17 1 1 209_splitncnn_5 211 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_5 1 4 211 211_splitncnn_0 211_splitncnn_1 211_splitncnn_2 211_splitncnn_3 +Concat Concat_19 2 1 209_splitncnn_4 211_splitncnn_3 212 +Convolution Conv_20 1 1 212 214 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_6 1 3 214 214_splitncnn_0 214_splitncnn_1 214_splitncnn_2 +Concat Concat_22 3 1 209_splitncnn_3 211_splitncnn_2 214_splitncnn_2 215 +Convolution Conv_23 1 1 215 217 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_7 1 2 217 217_splitncnn_0 217_splitncnn_1 +Concat Concat_25 4 1 209_splitncnn_2 211_splitncnn_1 214_splitncnn_1 217_splitncnn_1 218 +Convolution Conv_26 1 1 218 220 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_28 5 1 209_splitncnn_1 211_splitncnn_0 214_splitncnn_0 217_splitncnn_0 220 221 +Convolution Conv_29 1 1 221 222 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_32 2 1 222 209_splitncnn_0 225 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_8 1 6 225 225_splitncnn_0 225_splitncnn_1 225_splitncnn_2 225_splitncnn_3 225_splitncnn_4 225_splitncnn_5 +Convolution Conv_33 1 1 225_splitncnn_5 227 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_9 1 4 227 227_splitncnn_0 227_splitncnn_1 227_splitncnn_2 227_splitncnn_3 +Concat Concat_35 2 1 225_splitncnn_4 227_splitncnn_3 228 +Convolution Conv_36 1 1 228 230 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_10 1 3 230 230_splitncnn_0 230_splitncnn_1 230_splitncnn_2 +Concat Concat_38 3 1 225_splitncnn_3 227_splitncnn_2 230_splitncnn_2 231 +Convolution Conv_39 1 1 231 233 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_11 1 2 233 233_splitncnn_0 233_splitncnn_1 +Concat Concat_41 4 1 225_splitncnn_2 227_splitncnn_1 230_splitncnn_1 233_splitncnn_1 234 +Convolution Conv_42 1 1 234 236 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_44 5 1 225_splitncnn_1 227_splitncnn_0 230_splitncnn_0 233_splitncnn_0 236 237 +Convolution Conv_45 1 1 237 238 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_48 2 1 238 225_splitncnn_0 241 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_51 2 1 241 193_splitncnn_1 244 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_12 1 7 244 244_splitncnn_0 244_splitncnn_1 244_splitncnn_2 244_splitncnn_3 244_splitncnn_4 244_splitncnn_5 244_splitncnn_6 +Convolution Conv_52 1 1 244_splitncnn_6 246 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_13 1 4 246 246_splitncnn_0 246_splitncnn_1 246_splitncnn_2 246_splitncnn_3 +Concat Concat_54 2 1 244_splitncnn_5 246_splitncnn_3 247 +Convolution Conv_55 1 1 247 249 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_14 1 3 249 249_splitncnn_0 249_splitncnn_1 249_splitncnn_2 +Concat Concat_57 3 1 244_splitncnn_4 246_splitncnn_2 249_splitncnn_2 250 +Convolution Conv_58 1 1 250 252 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_15 1 2 252 252_splitncnn_0 252_splitncnn_1 +Concat Concat_60 4 1 244_splitncnn_3 246_splitncnn_1 249_splitncnn_1 252_splitncnn_1 253 +Convolution Conv_61 1 1 253 255 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_63 5 1 244_splitncnn_2 246_splitncnn_0 249_splitncnn_0 252_splitncnn_0 255 256 +Convolution Conv_64 1 1 256 257 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_67 2 1 257 244_splitncnn_1 260 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_16 1 6 260 260_splitncnn_0 260_splitncnn_1 260_splitncnn_2 260_splitncnn_3 260_splitncnn_4 260_splitncnn_5 +Convolution Conv_68 1 1 260_splitncnn_5 262 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_17 1 4 262 262_splitncnn_0 262_splitncnn_1 262_splitncnn_2 262_splitncnn_3 +Concat Concat_70 2 1 260_splitncnn_4 262_splitncnn_3 263 +Convolution Conv_71 1 1 263 265 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_18 1 3 265 265_splitncnn_0 265_splitncnn_1 265_splitncnn_2 +Concat Concat_73 3 1 260_splitncnn_3 262_splitncnn_2 265_splitncnn_2 266 +Convolution Conv_74 1 1 266 268 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_19 1 2 268 268_splitncnn_0 268_splitncnn_1 +Concat Concat_76 4 1 260_splitncnn_2 262_splitncnn_1 265_splitncnn_1 268_splitncnn_1 269 +Convolution Conv_77 1 1 269 271 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_79 5 1 260_splitncnn_1 262_splitncnn_0 265_splitncnn_0 268_splitncnn_0 271 272 +Convolution Conv_80 1 1 272 273 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_83 2 1 273 260_splitncnn_0 276 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_20 1 6 276 276_splitncnn_0 276_splitncnn_1 276_splitncnn_2 276_splitncnn_3 276_splitncnn_4 276_splitncnn_5 +Convolution Conv_84 1 1 276_splitncnn_5 278 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_21 1 4 278 278_splitncnn_0 278_splitncnn_1 278_splitncnn_2 278_splitncnn_3 +Concat Concat_86 2 1 276_splitncnn_4 278_splitncnn_3 279 +Convolution Conv_87 1 1 279 281 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_22 1 3 281 281_splitncnn_0 281_splitncnn_1 281_splitncnn_2 +Concat Concat_89 3 1 276_splitncnn_3 278_splitncnn_2 281_splitncnn_2 282 +Convolution Conv_90 1 1 282 284 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_23 1 2 284 284_splitncnn_0 284_splitncnn_1 +Concat Concat_92 4 1 276_splitncnn_2 278_splitncnn_1 281_splitncnn_1 284_splitncnn_1 285 +Convolution Conv_93 1 1 285 287 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_95 5 1 276_splitncnn_1 278_splitncnn_0 281_splitncnn_0 284_splitncnn_0 287 288 +Convolution Conv_96 1 1 288 289 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_99 2 1 289 276_splitncnn_0 292 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_102 2 1 292 244_splitncnn_0 295 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_24 1 7 295 295_splitncnn_0 295_splitncnn_1 295_splitncnn_2 295_splitncnn_3 295_splitncnn_4 295_splitncnn_5 295_splitncnn_6 +Convolution Conv_103 1 1 295_splitncnn_6 297 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_25 1 4 297 297_splitncnn_0 297_splitncnn_1 297_splitncnn_2 297_splitncnn_3 +Concat Concat_105 2 1 295_splitncnn_5 297_splitncnn_3 298 +Convolution Conv_106 1 1 298 300 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_26 1 3 300 300_splitncnn_0 300_splitncnn_1 300_splitncnn_2 +Concat Concat_108 3 1 295_splitncnn_4 297_splitncnn_2 300_splitncnn_2 301 +Convolution Conv_109 1 1 301 303 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_27 1 2 303 303_splitncnn_0 303_splitncnn_1 +Concat Concat_111 4 1 295_splitncnn_3 297_splitncnn_1 300_splitncnn_1 303_splitncnn_1 304 +Convolution Conv_112 1 1 304 306 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_114 5 1 295_splitncnn_2 297_splitncnn_0 300_splitncnn_0 303_splitncnn_0 306 307 +Convolution Conv_115 1 1 307 308 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_118 2 1 308 295_splitncnn_1 311 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_28 1 6 311 311_splitncnn_0 311_splitncnn_1 311_splitncnn_2 311_splitncnn_3 311_splitncnn_4 311_splitncnn_5 +Convolution Conv_119 1 1 311_splitncnn_5 313 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_29 1 4 313 313_splitncnn_0 313_splitncnn_1 313_splitncnn_2 313_splitncnn_3 +Concat Concat_121 2 1 311_splitncnn_4 313_splitncnn_3 314 +Convolution Conv_122 1 1 314 316 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_30 1 3 316 316_splitncnn_0 316_splitncnn_1 316_splitncnn_2 +Concat Concat_124 3 1 311_splitncnn_3 313_splitncnn_2 316_splitncnn_2 317 +Convolution Conv_125 1 1 317 319 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_31 1 2 319 319_splitncnn_0 319_splitncnn_1 +Concat Concat_127 4 1 311_splitncnn_2 313_splitncnn_1 316_splitncnn_1 319_splitncnn_1 320 +Convolution Conv_128 1 1 320 322 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_130 5 1 311_splitncnn_1 313_splitncnn_0 316_splitncnn_0 319_splitncnn_0 322 323 +Convolution Conv_131 1 1 323 324 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_134 2 1 324 311_splitncnn_0 327 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_32 1 6 327 327_splitncnn_0 327_splitncnn_1 327_splitncnn_2 327_splitncnn_3 327_splitncnn_4 327_splitncnn_5 +Convolution Conv_135 1 1 327_splitncnn_5 329 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_33 1 4 329 329_splitncnn_0 329_splitncnn_1 329_splitncnn_2 329_splitncnn_3 +Concat Concat_137 2 1 327_splitncnn_4 329_splitncnn_3 330 +Convolution Conv_138 1 1 330 332 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_34 1 3 332 332_splitncnn_0 332_splitncnn_1 332_splitncnn_2 +Concat Concat_140 3 1 327_splitncnn_3 329_splitncnn_2 332_splitncnn_2 333 +Convolution Conv_141 1 1 333 335 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_35 1 2 335 335_splitncnn_0 335_splitncnn_1 +Concat Concat_143 4 1 327_splitncnn_2 329_splitncnn_1 332_splitncnn_1 335_splitncnn_1 336 +Convolution Conv_144 1 1 336 338 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_146 5 1 327_splitncnn_1 329_splitncnn_0 332_splitncnn_0 335_splitncnn_0 338 339 +Convolution Conv_147 1 1 339 340 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_150 2 1 340 327_splitncnn_0 343 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_153 2 1 343 295_splitncnn_0 346 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_36 1 7 346 346_splitncnn_0 346_splitncnn_1 346_splitncnn_2 346_splitncnn_3 346_splitncnn_4 346_splitncnn_5 346_splitncnn_6 +Convolution Conv_154 1 1 346_splitncnn_6 348 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_37 1 4 348 348_splitncnn_0 348_splitncnn_1 348_splitncnn_2 348_splitncnn_3 +Concat Concat_156 2 1 346_splitncnn_5 348_splitncnn_3 349 +Convolution Conv_157 1 1 349 351 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_38 1 3 351 351_splitncnn_0 351_splitncnn_1 351_splitncnn_2 +Concat Concat_159 3 1 346_splitncnn_4 348_splitncnn_2 351_splitncnn_2 352 +Convolution Conv_160 1 1 352 354 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_39 1 2 354 354_splitncnn_0 354_splitncnn_1 +Concat Concat_162 4 1 346_splitncnn_3 348_splitncnn_1 351_splitncnn_1 354_splitncnn_1 355 +Convolution Conv_163 1 1 355 357 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_165 5 1 346_splitncnn_2 348_splitncnn_0 351_splitncnn_0 354_splitncnn_0 357 358 +Convolution Conv_166 1 1 358 359 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_169 2 1 359 346_splitncnn_1 362 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_40 1 6 362 362_splitncnn_0 362_splitncnn_1 362_splitncnn_2 362_splitncnn_3 362_splitncnn_4 362_splitncnn_5 +Convolution Conv_170 1 1 362_splitncnn_5 364 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_41 1 4 364 364_splitncnn_0 364_splitncnn_1 364_splitncnn_2 364_splitncnn_3 +Concat Concat_172 2 1 362_splitncnn_4 364_splitncnn_3 365 +Convolution Conv_173 1 1 365 367 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_42 1 3 367 367_splitncnn_0 367_splitncnn_1 367_splitncnn_2 +Concat Concat_175 3 1 362_splitncnn_3 364_splitncnn_2 367_splitncnn_2 368 +Convolution Conv_176 1 1 368 370 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_43 1 2 370 370_splitncnn_0 370_splitncnn_1 +Concat Concat_178 4 1 362_splitncnn_2 364_splitncnn_1 367_splitncnn_1 370_splitncnn_1 371 +Convolution Conv_179 1 1 371 373 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_181 5 1 362_splitncnn_1 364_splitncnn_0 367_splitncnn_0 370_splitncnn_0 373 374 +Convolution Conv_182 1 1 374 375 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_185 2 1 375 362_splitncnn_0 378 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_44 1 6 378 378_splitncnn_0 378_splitncnn_1 378_splitncnn_2 378_splitncnn_3 378_splitncnn_4 378_splitncnn_5 +Convolution Conv_186 1 1 378_splitncnn_5 380 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_45 1 4 380 380_splitncnn_0 380_splitncnn_1 380_splitncnn_2 380_splitncnn_3 +Concat Concat_188 2 1 378_splitncnn_4 380_splitncnn_3 381 +Convolution Conv_189 1 1 381 383 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_46 1 3 383 383_splitncnn_0 383_splitncnn_1 383_splitncnn_2 +Concat Concat_191 3 1 378_splitncnn_3 380_splitncnn_2 383_splitncnn_2 384 +Convolution Conv_192 1 1 384 386 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_47 1 2 386 386_splitncnn_0 386_splitncnn_1 +Concat Concat_194 4 1 378_splitncnn_2 380_splitncnn_1 383_splitncnn_1 386_splitncnn_1 387 +Convolution Conv_195 1 1 387 389 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_197 5 1 378_splitncnn_1 380_splitncnn_0 383_splitncnn_0 386_splitncnn_0 389 390 +Convolution Conv_198 1 1 390 391 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_201 2 1 391 378_splitncnn_0 394 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_204 2 1 394 346_splitncnn_0 397 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_48 1 7 397 397_splitncnn_0 397_splitncnn_1 397_splitncnn_2 397_splitncnn_3 397_splitncnn_4 397_splitncnn_5 397_splitncnn_6 +Convolution Conv_205 1 1 397_splitncnn_6 399 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_49 1 4 399 399_splitncnn_0 399_splitncnn_1 399_splitncnn_2 399_splitncnn_3 +Concat Concat_207 2 1 397_splitncnn_5 399_splitncnn_3 400 +Convolution Conv_208 1 1 400 402 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_50 1 3 402 402_splitncnn_0 402_splitncnn_1 402_splitncnn_2 +Concat Concat_210 3 1 397_splitncnn_4 399_splitncnn_2 402_splitncnn_2 403 +Convolution Conv_211 1 1 403 405 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_51 1 2 405 405_splitncnn_0 405_splitncnn_1 +Concat Concat_213 4 1 397_splitncnn_3 399_splitncnn_1 402_splitncnn_1 405_splitncnn_1 406 +Convolution Conv_214 1 1 406 408 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_216 5 1 397_splitncnn_2 399_splitncnn_0 402_splitncnn_0 405_splitncnn_0 408 409 +Convolution Conv_217 1 1 409 410 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_220 2 1 410 397_splitncnn_1 413 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_52 1 6 413 413_splitncnn_0 413_splitncnn_1 413_splitncnn_2 413_splitncnn_3 413_splitncnn_4 413_splitncnn_5 +Convolution Conv_221 1 1 413_splitncnn_5 415 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_53 1 4 415 415_splitncnn_0 415_splitncnn_1 415_splitncnn_2 415_splitncnn_3 +Concat Concat_223 2 1 413_splitncnn_4 415_splitncnn_3 416 +Convolution Conv_224 1 1 416 418 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_54 1 3 418 418_splitncnn_0 418_splitncnn_1 418_splitncnn_2 +Concat Concat_226 3 1 413_splitncnn_3 415_splitncnn_2 418_splitncnn_2 419 +Convolution Conv_227 1 1 419 421 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_55 1 2 421 421_splitncnn_0 421_splitncnn_1 +Concat Concat_229 4 1 413_splitncnn_2 415_splitncnn_1 418_splitncnn_1 421_splitncnn_1 422 +Convolution Conv_230 1 1 422 424 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_232 5 1 413_splitncnn_1 415_splitncnn_0 418_splitncnn_0 421_splitncnn_0 424 425 +Convolution Conv_233 1 1 425 426 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_236 2 1 426 413_splitncnn_0 429 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_56 1 6 429 429_splitncnn_0 429_splitncnn_1 429_splitncnn_2 429_splitncnn_3 429_splitncnn_4 429_splitncnn_5 +Convolution Conv_237 1 1 429_splitncnn_5 431 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_57 1 4 431 431_splitncnn_0 431_splitncnn_1 431_splitncnn_2 431_splitncnn_3 +Concat Concat_239 2 1 429_splitncnn_4 431_splitncnn_3 432 +Convolution Conv_240 1 1 432 434 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_58 1 3 434 434_splitncnn_0 434_splitncnn_1 434_splitncnn_2 +Concat Concat_242 3 1 429_splitncnn_3 431_splitncnn_2 434_splitncnn_2 435 +Convolution Conv_243 1 1 435 437 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_59 1 2 437 437_splitncnn_0 437_splitncnn_1 +Concat Concat_245 4 1 429_splitncnn_2 431_splitncnn_1 434_splitncnn_1 437_splitncnn_1 438 +Convolution Conv_246 1 1 438 440 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_248 5 1 429_splitncnn_1 431_splitncnn_0 434_splitncnn_0 437_splitncnn_0 440 441 +Convolution Conv_249 1 1 441 442 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_252 2 1 442 429_splitncnn_0 445 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_255 2 1 445 397_splitncnn_0 448 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_60 1 7 448 448_splitncnn_0 448_splitncnn_1 448_splitncnn_2 448_splitncnn_3 448_splitncnn_4 448_splitncnn_5 448_splitncnn_6 +Convolution Conv_256 1 1 448_splitncnn_6 450 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_61 1 4 450 450_splitncnn_0 450_splitncnn_1 450_splitncnn_2 450_splitncnn_3 +Concat Concat_258 2 1 448_splitncnn_5 450_splitncnn_3 451 +Convolution Conv_259 1 1 451 453 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_62 1 3 453 453_splitncnn_0 453_splitncnn_1 453_splitncnn_2 +Concat Concat_261 3 1 448_splitncnn_4 450_splitncnn_2 453_splitncnn_2 454 +Convolution Conv_262 1 1 454 456 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_63 1 2 456 456_splitncnn_0 456_splitncnn_1 +Concat Concat_264 4 1 448_splitncnn_3 450_splitncnn_1 453_splitncnn_1 456_splitncnn_1 457 +Convolution Conv_265 1 1 457 459 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_267 5 1 448_splitncnn_2 450_splitncnn_0 453_splitncnn_0 456_splitncnn_0 459 460 +Convolution Conv_268 1 1 460 461 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_271 2 1 461 448_splitncnn_1 464 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_64 1 6 464 464_splitncnn_0 464_splitncnn_1 464_splitncnn_2 464_splitncnn_3 464_splitncnn_4 464_splitncnn_5 +Convolution Conv_272 1 1 464_splitncnn_5 466 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_65 1 4 466 466_splitncnn_0 466_splitncnn_1 466_splitncnn_2 466_splitncnn_3 +Concat Concat_274 2 1 464_splitncnn_4 466_splitncnn_3 467 +Convolution Conv_275 1 1 467 469 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_66 1 3 469 469_splitncnn_0 469_splitncnn_1 469_splitncnn_2 +Concat Concat_277 3 1 464_splitncnn_3 466_splitncnn_2 469_splitncnn_2 470 +Convolution Conv_278 1 1 470 472 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_67 1 2 472 472_splitncnn_0 472_splitncnn_1 +Concat Concat_280 4 1 464_splitncnn_2 466_splitncnn_1 469_splitncnn_1 472_splitncnn_1 473 +Convolution Conv_281 1 1 473 475 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_283 5 1 464_splitncnn_1 466_splitncnn_0 469_splitncnn_0 472_splitncnn_0 475 476 +Convolution Conv_284 1 1 476 477 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_287 2 1 477 464_splitncnn_0 480 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_68 1 6 480 480_splitncnn_0 480_splitncnn_1 480_splitncnn_2 480_splitncnn_3 480_splitncnn_4 480_splitncnn_5 +Convolution Conv_288 1 1 480_splitncnn_5 482 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_69 1 4 482 482_splitncnn_0 482_splitncnn_1 482_splitncnn_2 482_splitncnn_3 +Concat Concat_290 2 1 480_splitncnn_4 482_splitncnn_3 483 +Convolution Conv_291 1 1 483 485 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_70 1 3 485 485_splitncnn_0 485_splitncnn_1 485_splitncnn_2 +Concat Concat_293 3 1 480_splitncnn_3 482_splitncnn_2 485_splitncnn_2 486 +Convolution Conv_294 1 1 486 488 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_71 1 2 488 488_splitncnn_0 488_splitncnn_1 +Concat Concat_296 4 1 480_splitncnn_2 482_splitncnn_1 485_splitncnn_1 488_splitncnn_1 489 +Convolution Conv_297 1 1 489 491 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_299 5 1 480_splitncnn_1 482_splitncnn_0 485_splitncnn_0 488_splitncnn_0 491 492 +Convolution Conv_300 1 1 492 493 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_303 2 1 493 480_splitncnn_0 496 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_306 2 1 496 448_splitncnn_0 499 0=1 -23301=2,2.000000e-01,1.000000e+00 +Convolution Conv_307 1 1 499 500 0=64 1=3 4=1 5=1 6=36864 +BinaryOp Add_308 2 1 193_splitncnn_0 500 501 +Interp Resize_310 1 1 501 506 0=1 1=2.000000e+00 2=2.000000e+00 +Convolution Conv_311 1 1 506 508 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Interp Resize_314 1 1 508 513 0=1 1=2.000000e+00 2=2.000000e+00 +Convolution Conv_315 1 1 513 515 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Convolution Conv_317 1 1 515 517 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Convolution Conv_319 1 1 517 output 0=3 1=3 4=1 5=1 6=1728 diff --git a/realesrgan-bin/models/realesrgan-x4plus.bin b/realesrgan-bin/models/realesrgan-x4plus.bin new file mode 100644 index 0000000..5cea947 Binary files /dev/null and b/realesrgan-bin/models/realesrgan-x4plus.bin differ diff --git a/realesrgan-bin/models/realesrgan-x4plus.param b/realesrgan-bin/models/realesrgan-x4plus.param new file mode 100644 index 0000000..d14d62e --- /dev/null +++ b/realesrgan-bin/models/realesrgan-x4plus.param @@ -0,0 +1,1001 @@ +7767517 +999 1782 +Input input.1 0 1 data +Convolution Conv_0 1 1 data 703 0=64 1=3 4=1 5=1 6=1728 +Split splitncnn_0 1 8 703 703_splitncnn_0 703_splitncnn_1 703_splitncnn_2 703_splitncnn_3 703_splitncnn_4 703_splitncnn_5 703_splitncnn_6 703_splitncnn_7 +Convolution Conv_1 1 1 703_splitncnn_7 705 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_1 1 4 705 705_splitncnn_0 705_splitncnn_1 705_splitncnn_2 705_splitncnn_3 +Concat Concat_3 2 1 703_splitncnn_6 705_splitncnn_3 706 +Convolution Conv_4 1 1 706 708 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_2 1 3 708 708_splitncnn_0 708_splitncnn_1 708_splitncnn_2 +Concat Concat_6 3 1 703_splitncnn_5 705_splitncnn_2 708_splitncnn_2 709 +Convolution Conv_7 1 1 709 711 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_3 1 2 711 711_splitncnn_0 711_splitncnn_1 +Concat Concat_9 4 1 703_splitncnn_4 705_splitncnn_1 708_splitncnn_1 711_splitncnn_1 712 +Convolution Conv_10 1 1 712 714 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_12 5 1 703_splitncnn_3 705_splitncnn_0 708_splitncnn_0 711_splitncnn_0 714 715 +Convolution Conv_13 1 1 715 716 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_16 2 1 716 703_splitncnn_2 719 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_4 1 6 719 719_splitncnn_0 719_splitncnn_1 719_splitncnn_2 719_splitncnn_3 719_splitncnn_4 719_splitncnn_5 +Convolution Conv_17 1 1 719_splitncnn_5 721 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_5 1 4 721 721_splitncnn_0 721_splitncnn_1 721_splitncnn_2 721_splitncnn_3 +Concat Concat_19 2 1 719_splitncnn_4 721_splitncnn_3 722 +Convolution Conv_20 1 1 722 724 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_6 1 3 724 724_splitncnn_0 724_splitncnn_1 724_splitncnn_2 +Concat Concat_22 3 1 719_splitncnn_3 721_splitncnn_2 724_splitncnn_2 725 +Convolution Conv_23 1 1 725 727 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_7 1 2 727 727_splitncnn_0 727_splitncnn_1 +Concat Concat_25 4 1 719_splitncnn_2 721_splitncnn_1 724_splitncnn_1 727_splitncnn_1 728 +Convolution Conv_26 1 1 728 730 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_28 5 1 719_splitncnn_1 721_splitncnn_0 724_splitncnn_0 727_splitncnn_0 730 731 +Convolution Conv_29 1 1 731 732 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_32 2 1 732 719_splitncnn_0 735 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_8 1 6 735 735_splitncnn_0 735_splitncnn_1 735_splitncnn_2 735_splitncnn_3 735_splitncnn_4 735_splitncnn_5 +Convolution Conv_33 1 1 735_splitncnn_5 737 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_9 1 4 737 737_splitncnn_0 737_splitncnn_1 737_splitncnn_2 737_splitncnn_3 +Concat Concat_35 2 1 735_splitncnn_4 737_splitncnn_3 738 +Convolution Conv_36 1 1 738 740 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_10 1 3 740 740_splitncnn_0 740_splitncnn_1 740_splitncnn_2 +Concat Concat_38 3 1 735_splitncnn_3 737_splitncnn_2 740_splitncnn_2 741 +Convolution Conv_39 1 1 741 743 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_11 1 2 743 743_splitncnn_0 743_splitncnn_1 +Concat Concat_41 4 1 735_splitncnn_2 737_splitncnn_1 740_splitncnn_1 743_splitncnn_1 744 +Convolution Conv_42 1 1 744 746 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_44 5 1 735_splitncnn_1 737_splitncnn_0 740_splitncnn_0 743_splitncnn_0 746 747 +Convolution Conv_45 1 1 747 748 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_48 2 1 748 735_splitncnn_0 751 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_51 2 1 751 703_splitncnn_1 754 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_12 1 7 754 754_splitncnn_0 754_splitncnn_1 754_splitncnn_2 754_splitncnn_3 754_splitncnn_4 754_splitncnn_5 754_splitncnn_6 +Convolution Conv_52 1 1 754_splitncnn_6 756 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_13 1 4 756 756_splitncnn_0 756_splitncnn_1 756_splitncnn_2 756_splitncnn_3 +Concat Concat_54 2 1 754_splitncnn_5 756_splitncnn_3 757 +Convolution Conv_55 1 1 757 759 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_14 1 3 759 759_splitncnn_0 759_splitncnn_1 759_splitncnn_2 +Concat Concat_57 3 1 754_splitncnn_4 756_splitncnn_2 759_splitncnn_2 760 +Convolution Conv_58 1 1 760 762 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_15 1 2 762 762_splitncnn_0 762_splitncnn_1 +Concat Concat_60 4 1 754_splitncnn_3 756_splitncnn_1 759_splitncnn_1 762_splitncnn_1 763 +Convolution Conv_61 1 1 763 765 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_63 5 1 754_splitncnn_2 756_splitncnn_0 759_splitncnn_0 762_splitncnn_0 765 766 +Convolution Conv_64 1 1 766 767 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_67 2 1 767 754_splitncnn_1 770 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_16 1 6 770 770_splitncnn_0 770_splitncnn_1 770_splitncnn_2 770_splitncnn_3 770_splitncnn_4 770_splitncnn_5 +Convolution Conv_68 1 1 770_splitncnn_5 772 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_17 1 4 772 772_splitncnn_0 772_splitncnn_1 772_splitncnn_2 772_splitncnn_3 +Concat Concat_70 2 1 770_splitncnn_4 772_splitncnn_3 773 +Convolution Conv_71 1 1 773 775 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_18 1 3 775 775_splitncnn_0 775_splitncnn_1 775_splitncnn_2 +Concat Concat_73 3 1 770_splitncnn_3 772_splitncnn_2 775_splitncnn_2 776 +Convolution Conv_74 1 1 776 778 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_19 1 2 778 778_splitncnn_0 778_splitncnn_1 +Concat Concat_76 4 1 770_splitncnn_2 772_splitncnn_1 775_splitncnn_1 778_splitncnn_1 779 +Convolution Conv_77 1 1 779 781 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_79 5 1 770_splitncnn_1 772_splitncnn_0 775_splitncnn_0 778_splitncnn_0 781 782 +Convolution Conv_80 1 1 782 783 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_83 2 1 783 770_splitncnn_0 786 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_20 1 6 786 786_splitncnn_0 786_splitncnn_1 786_splitncnn_2 786_splitncnn_3 786_splitncnn_4 786_splitncnn_5 +Convolution Conv_84 1 1 786_splitncnn_5 788 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_21 1 4 788 788_splitncnn_0 788_splitncnn_1 788_splitncnn_2 788_splitncnn_3 +Concat Concat_86 2 1 786_splitncnn_4 788_splitncnn_3 789 +Convolution Conv_87 1 1 789 791 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_22 1 3 791 791_splitncnn_0 791_splitncnn_1 791_splitncnn_2 +Concat Concat_89 3 1 786_splitncnn_3 788_splitncnn_2 791_splitncnn_2 792 +Convolution Conv_90 1 1 792 794 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_23 1 2 794 794_splitncnn_0 794_splitncnn_1 +Concat Concat_92 4 1 786_splitncnn_2 788_splitncnn_1 791_splitncnn_1 794_splitncnn_1 795 +Convolution Conv_93 1 1 795 797 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_95 5 1 786_splitncnn_1 788_splitncnn_0 791_splitncnn_0 794_splitncnn_0 797 798 +Convolution Conv_96 1 1 798 799 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_99 2 1 799 786_splitncnn_0 802 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_102 2 1 802 754_splitncnn_0 805 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_24 1 7 805 805_splitncnn_0 805_splitncnn_1 805_splitncnn_2 805_splitncnn_3 805_splitncnn_4 805_splitncnn_5 805_splitncnn_6 +Convolution Conv_103 1 1 805_splitncnn_6 807 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_25 1 4 807 807_splitncnn_0 807_splitncnn_1 807_splitncnn_2 807_splitncnn_3 +Concat Concat_105 2 1 805_splitncnn_5 807_splitncnn_3 808 +Convolution Conv_106 1 1 808 810 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_26 1 3 810 810_splitncnn_0 810_splitncnn_1 810_splitncnn_2 +Concat Concat_108 3 1 805_splitncnn_4 807_splitncnn_2 810_splitncnn_2 811 +Convolution Conv_109 1 1 811 813 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_27 1 2 813 813_splitncnn_0 813_splitncnn_1 +Concat Concat_111 4 1 805_splitncnn_3 807_splitncnn_1 810_splitncnn_1 813_splitncnn_1 814 +Convolution Conv_112 1 1 814 816 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_114 5 1 805_splitncnn_2 807_splitncnn_0 810_splitncnn_0 813_splitncnn_0 816 817 +Convolution Conv_115 1 1 817 818 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_118 2 1 818 805_splitncnn_1 821 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_28 1 6 821 821_splitncnn_0 821_splitncnn_1 821_splitncnn_2 821_splitncnn_3 821_splitncnn_4 821_splitncnn_5 +Convolution Conv_119 1 1 821_splitncnn_5 823 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_29 1 4 823 823_splitncnn_0 823_splitncnn_1 823_splitncnn_2 823_splitncnn_3 +Concat Concat_121 2 1 821_splitncnn_4 823_splitncnn_3 824 +Convolution Conv_122 1 1 824 826 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_30 1 3 826 826_splitncnn_0 826_splitncnn_1 826_splitncnn_2 +Concat Concat_124 3 1 821_splitncnn_3 823_splitncnn_2 826_splitncnn_2 827 +Convolution Conv_125 1 1 827 829 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_31 1 2 829 829_splitncnn_0 829_splitncnn_1 +Concat Concat_127 4 1 821_splitncnn_2 823_splitncnn_1 826_splitncnn_1 829_splitncnn_1 830 +Convolution Conv_128 1 1 830 832 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_130 5 1 821_splitncnn_1 823_splitncnn_0 826_splitncnn_0 829_splitncnn_0 832 833 +Convolution Conv_131 1 1 833 834 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_134 2 1 834 821_splitncnn_0 837 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_32 1 6 837 837_splitncnn_0 837_splitncnn_1 837_splitncnn_2 837_splitncnn_3 837_splitncnn_4 837_splitncnn_5 +Convolution Conv_135 1 1 837_splitncnn_5 839 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_33 1 4 839 839_splitncnn_0 839_splitncnn_1 839_splitncnn_2 839_splitncnn_3 +Concat Concat_137 2 1 837_splitncnn_4 839_splitncnn_3 840 +Convolution Conv_138 1 1 840 842 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_34 1 3 842 842_splitncnn_0 842_splitncnn_1 842_splitncnn_2 +Concat Concat_140 3 1 837_splitncnn_3 839_splitncnn_2 842_splitncnn_2 843 +Convolution Conv_141 1 1 843 845 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_35 1 2 845 845_splitncnn_0 845_splitncnn_1 +Concat Concat_143 4 1 837_splitncnn_2 839_splitncnn_1 842_splitncnn_1 845_splitncnn_1 846 +Convolution Conv_144 1 1 846 848 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_146 5 1 837_splitncnn_1 839_splitncnn_0 842_splitncnn_0 845_splitncnn_0 848 849 +Convolution Conv_147 1 1 849 850 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_150 2 1 850 837_splitncnn_0 853 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_153 2 1 853 805_splitncnn_0 856 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_36 1 7 856 856_splitncnn_0 856_splitncnn_1 856_splitncnn_2 856_splitncnn_3 856_splitncnn_4 856_splitncnn_5 856_splitncnn_6 +Convolution Conv_154 1 1 856_splitncnn_6 858 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_37 1 4 858 858_splitncnn_0 858_splitncnn_1 858_splitncnn_2 858_splitncnn_3 +Concat Concat_156 2 1 856_splitncnn_5 858_splitncnn_3 859 +Convolution Conv_157 1 1 859 861 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_38 1 3 861 861_splitncnn_0 861_splitncnn_1 861_splitncnn_2 +Concat Concat_159 3 1 856_splitncnn_4 858_splitncnn_2 861_splitncnn_2 862 +Convolution Conv_160 1 1 862 864 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_39 1 2 864 864_splitncnn_0 864_splitncnn_1 +Concat Concat_162 4 1 856_splitncnn_3 858_splitncnn_1 861_splitncnn_1 864_splitncnn_1 865 +Convolution Conv_163 1 1 865 867 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_165 5 1 856_splitncnn_2 858_splitncnn_0 861_splitncnn_0 864_splitncnn_0 867 868 +Convolution Conv_166 1 1 868 869 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_169 2 1 869 856_splitncnn_1 872 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_40 1 6 872 872_splitncnn_0 872_splitncnn_1 872_splitncnn_2 872_splitncnn_3 872_splitncnn_4 872_splitncnn_5 +Convolution Conv_170 1 1 872_splitncnn_5 874 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_41 1 4 874 874_splitncnn_0 874_splitncnn_1 874_splitncnn_2 874_splitncnn_3 +Concat Concat_172 2 1 872_splitncnn_4 874_splitncnn_3 875 +Convolution Conv_173 1 1 875 877 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_42 1 3 877 877_splitncnn_0 877_splitncnn_1 877_splitncnn_2 +Concat Concat_175 3 1 872_splitncnn_3 874_splitncnn_2 877_splitncnn_2 878 +Convolution Conv_176 1 1 878 880 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_43 1 2 880 880_splitncnn_0 880_splitncnn_1 +Concat Concat_178 4 1 872_splitncnn_2 874_splitncnn_1 877_splitncnn_1 880_splitncnn_1 881 +Convolution Conv_179 1 1 881 883 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_181 5 1 872_splitncnn_1 874_splitncnn_0 877_splitncnn_0 880_splitncnn_0 883 884 +Convolution Conv_182 1 1 884 885 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_185 2 1 885 872_splitncnn_0 888 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_44 1 6 888 888_splitncnn_0 888_splitncnn_1 888_splitncnn_2 888_splitncnn_3 888_splitncnn_4 888_splitncnn_5 +Convolution Conv_186 1 1 888_splitncnn_5 890 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_45 1 4 890 890_splitncnn_0 890_splitncnn_1 890_splitncnn_2 890_splitncnn_3 +Concat Concat_188 2 1 888_splitncnn_4 890_splitncnn_3 891 +Convolution Conv_189 1 1 891 893 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_46 1 3 893 893_splitncnn_0 893_splitncnn_1 893_splitncnn_2 +Concat Concat_191 3 1 888_splitncnn_3 890_splitncnn_2 893_splitncnn_2 894 +Convolution Conv_192 1 1 894 896 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_47 1 2 896 896_splitncnn_0 896_splitncnn_1 +Concat Concat_194 4 1 888_splitncnn_2 890_splitncnn_1 893_splitncnn_1 896_splitncnn_1 897 +Convolution Conv_195 1 1 897 899 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_197 5 1 888_splitncnn_1 890_splitncnn_0 893_splitncnn_0 896_splitncnn_0 899 900 +Convolution Conv_198 1 1 900 901 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_201 2 1 901 888_splitncnn_0 904 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_204 2 1 904 856_splitncnn_0 907 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_48 1 7 907 907_splitncnn_0 907_splitncnn_1 907_splitncnn_2 907_splitncnn_3 907_splitncnn_4 907_splitncnn_5 907_splitncnn_6 +Convolution Conv_205 1 1 907_splitncnn_6 909 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_49 1 4 909 909_splitncnn_0 909_splitncnn_1 909_splitncnn_2 909_splitncnn_3 +Concat Concat_207 2 1 907_splitncnn_5 909_splitncnn_3 910 +Convolution Conv_208 1 1 910 912 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_50 1 3 912 912_splitncnn_0 912_splitncnn_1 912_splitncnn_2 +Concat Concat_210 3 1 907_splitncnn_4 909_splitncnn_2 912_splitncnn_2 913 +Convolution Conv_211 1 1 913 915 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_51 1 2 915 915_splitncnn_0 915_splitncnn_1 +Concat Concat_213 4 1 907_splitncnn_3 909_splitncnn_1 912_splitncnn_1 915_splitncnn_1 916 +Convolution Conv_214 1 1 916 918 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_216 5 1 907_splitncnn_2 909_splitncnn_0 912_splitncnn_0 915_splitncnn_0 918 919 +Convolution Conv_217 1 1 919 920 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_220 2 1 920 907_splitncnn_1 923 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_52 1 6 923 923_splitncnn_0 923_splitncnn_1 923_splitncnn_2 923_splitncnn_3 923_splitncnn_4 923_splitncnn_5 +Convolution Conv_221 1 1 923_splitncnn_5 925 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_53 1 4 925 925_splitncnn_0 925_splitncnn_1 925_splitncnn_2 925_splitncnn_3 +Concat Concat_223 2 1 923_splitncnn_4 925_splitncnn_3 926 +Convolution Conv_224 1 1 926 928 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_54 1 3 928 928_splitncnn_0 928_splitncnn_1 928_splitncnn_2 +Concat Concat_226 3 1 923_splitncnn_3 925_splitncnn_2 928_splitncnn_2 929 +Convolution Conv_227 1 1 929 931 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_55 1 2 931 931_splitncnn_0 931_splitncnn_1 +Concat Concat_229 4 1 923_splitncnn_2 925_splitncnn_1 928_splitncnn_1 931_splitncnn_1 932 +Convolution Conv_230 1 1 932 934 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_232 5 1 923_splitncnn_1 925_splitncnn_0 928_splitncnn_0 931_splitncnn_0 934 935 +Convolution Conv_233 1 1 935 936 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_236 2 1 936 923_splitncnn_0 939 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_56 1 6 939 939_splitncnn_0 939_splitncnn_1 939_splitncnn_2 939_splitncnn_3 939_splitncnn_4 939_splitncnn_5 +Convolution Conv_237 1 1 939_splitncnn_5 941 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_57 1 4 941 941_splitncnn_0 941_splitncnn_1 941_splitncnn_2 941_splitncnn_3 +Concat Concat_239 2 1 939_splitncnn_4 941_splitncnn_3 942 +Convolution Conv_240 1 1 942 944 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_58 1 3 944 944_splitncnn_0 944_splitncnn_1 944_splitncnn_2 +Concat Concat_242 3 1 939_splitncnn_3 941_splitncnn_2 944_splitncnn_2 945 +Convolution Conv_243 1 1 945 947 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_59 1 2 947 947_splitncnn_0 947_splitncnn_1 +Concat Concat_245 4 1 939_splitncnn_2 941_splitncnn_1 944_splitncnn_1 947_splitncnn_1 948 +Convolution Conv_246 1 1 948 950 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_248 5 1 939_splitncnn_1 941_splitncnn_0 944_splitncnn_0 947_splitncnn_0 950 951 +Convolution Conv_249 1 1 951 952 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_252 2 1 952 939_splitncnn_0 955 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_255 2 1 955 907_splitncnn_0 958 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_60 1 7 958 958_splitncnn_0 958_splitncnn_1 958_splitncnn_2 958_splitncnn_3 958_splitncnn_4 958_splitncnn_5 958_splitncnn_6 +Convolution Conv_256 1 1 958_splitncnn_6 960 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_61 1 4 960 960_splitncnn_0 960_splitncnn_1 960_splitncnn_2 960_splitncnn_3 +Concat Concat_258 2 1 958_splitncnn_5 960_splitncnn_3 961 +Convolution Conv_259 1 1 961 963 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_62 1 3 963 963_splitncnn_0 963_splitncnn_1 963_splitncnn_2 +Concat Concat_261 3 1 958_splitncnn_4 960_splitncnn_2 963_splitncnn_2 964 +Convolution Conv_262 1 1 964 966 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_63 1 2 966 966_splitncnn_0 966_splitncnn_1 +Concat Concat_264 4 1 958_splitncnn_3 960_splitncnn_1 963_splitncnn_1 966_splitncnn_1 967 +Convolution Conv_265 1 1 967 969 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_267 5 1 958_splitncnn_2 960_splitncnn_0 963_splitncnn_0 966_splitncnn_0 969 970 +Convolution Conv_268 1 1 970 971 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_271 2 1 971 958_splitncnn_1 974 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_64 1 6 974 974_splitncnn_0 974_splitncnn_1 974_splitncnn_2 974_splitncnn_3 974_splitncnn_4 974_splitncnn_5 +Convolution Conv_272 1 1 974_splitncnn_5 976 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_65 1 4 976 976_splitncnn_0 976_splitncnn_1 976_splitncnn_2 976_splitncnn_3 +Concat Concat_274 2 1 974_splitncnn_4 976_splitncnn_3 977 +Convolution Conv_275 1 1 977 979 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_66 1 3 979 979_splitncnn_0 979_splitncnn_1 979_splitncnn_2 +Concat Concat_277 3 1 974_splitncnn_3 976_splitncnn_2 979_splitncnn_2 980 +Convolution Conv_278 1 1 980 982 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_67 1 2 982 982_splitncnn_0 982_splitncnn_1 +Concat Concat_280 4 1 974_splitncnn_2 976_splitncnn_1 979_splitncnn_1 982_splitncnn_1 983 +Convolution Conv_281 1 1 983 985 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_283 5 1 974_splitncnn_1 976_splitncnn_0 979_splitncnn_0 982_splitncnn_0 985 986 +Convolution Conv_284 1 1 986 987 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_287 2 1 987 974_splitncnn_0 990 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_68 1 6 990 990_splitncnn_0 990_splitncnn_1 990_splitncnn_2 990_splitncnn_3 990_splitncnn_4 990_splitncnn_5 +Convolution Conv_288 1 1 990_splitncnn_5 992 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_69 1 4 992 992_splitncnn_0 992_splitncnn_1 992_splitncnn_2 992_splitncnn_3 +Concat Concat_290 2 1 990_splitncnn_4 992_splitncnn_3 993 +Convolution Conv_291 1 1 993 995 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_70 1 3 995 995_splitncnn_0 995_splitncnn_1 995_splitncnn_2 +Concat Concat_293 3 1 990_splitncnn_3 992_splitncnn_2 995_splitncnn_2 996 +Convolution Conv_294 1 1 996 998 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_71 1 2 998 998_splitncnn_0 998_splitncnn_1 +Concat Concat_296 4 1 990_splitncnn_2 992_splitncnn_1 995_splitncnn_1 998_splitncnn_1 999 +Convolution Conv_297 1 1 999 1001 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_299 5 1 990_splitncnn_1 992_splitncnn_0 995_splitncnn_0 998_splitncnn_0 1001 1002 +Convolution Conv_300 1 1 1002 1003 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_303 2 1 1003 990_splitncnn_0 1006 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_306 2 1 1006 958_splitncnn_0 1009 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_72 1 7 1009 1009_splitncnn_0 1009_splitncnn_1 1009_splitncnn_2 1009_splitncnn_3 1009_splitncnn_4 1009_splitncnn_5 1009_splitncnn_6 +Convolution Conv_307 1 1 1009_splitncnn_6 1011 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_73 1 4 1011 1011_splitncnn_0 1011_splitncnn_1 1011_splitncnn_2 1011_splitncnn_3 +Concat Concat_309 2 1 1009_splitncnn_5 1011_splitncnn_3 1012 +Convolution Conv_310 1 1 1012 1014 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_74 1 3 1014 1014_splitncnn_0 1014_splitncnn_1 1014_splitncnn_2 +Concat Concat_312 3 1 1009_splitncnn_4 1011_splitncnn_2 1014_splitncnn_2 1015 +Convolution Conv_313 1 1 1015 1017 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_75 1 2 1017 1017_splitncnn_0 1017_splitncnn_1 +Concat Concat_315 4 1 1009_splitncnn_3 1011_splitncnn_1 1014_splitncnn_1 1017_splitncnn_1 1018 +Convolution Conv_316 1 1 1018 1020 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_318 5 1 1009_splitncnn_2 1011_splitncnn_0 1014_splitncnn_0 1017_splitncnn_0 1020 1021 +Convolution Conv_319 1 1 1021 1022 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_322 2 1 1022 1009_splitncnn_1 1025 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_76 1 6 1025 1025_splitncnn_0 1025_splitncnn_1 1025_splitncnn_2 1025_splitncnn_3 1025_splitncnn_4 1025_splitncnn_5 +Convolution Conv_323 1 1 1025_splitncnn_5 1027 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_77 1 4 1027 1027_splitncnn_0 1027_splitncnn_1 1027_splitncnn_2 1027_splitncnn_3 +Concat Concat_325 2 1 1025_splitncnn_4 1027_splitncnn_3 1028 +Convolution Conv_326 1 1 1028 1030 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_78 1 3 1030 1030_splitncnn_0 1030_splitncnn_1 1030_splitncnn_2 +Concat Concat_328 3 1 1025_splitncnn_3 1027_splitncnn_2 1030_splitncnn_2 1031 +Convolution Conv_329 1 1 1031 1033 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_79 1 2 1033 1033_splitncnn_0 1033_splitncnn_1 +Concat Concat_331 4 1 1025_splitncnn_2 1027_splitncnn_1 1030_splitncnn_1 1033_splitncnn_1 1034 +Convolution Conv_332 1 1 1034 1036 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_334 5 1 1025_splitncnn_1 1027_splitncnn_0 1030_splitncnn_0 1033_splitncnn_0 1036 1037 +Convolution Conv_335 1 1 1037 1038 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_338 2 1 1038 1025_splitncnn_0 1041 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_80 1 6 1041 1041_splitncnn_0 1041_splitncnn_1 1041_splitncnn_2 1041_splitncnn_3 1041_splitncnn_4 1041_splitncnn_5 +Convolution Conv_339 1 1 1041_splitncnn_5 1043 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_81 1 4 1043 1043_splitncnn_0 1043_splitncnn_1 1043_splitncnn_2 1043_splitncnn_3 +Concat Concat_341 2 1 1041_splitncnn_4 1043_splitncnn_3 1044 +Convolution Conv_342 1 1 1044 1046 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_82 1 3 1046 1046_splitncnn_0 1046_splitncnn_1 1046_splitncnn_2 +Concat Concat_344 3 1 1041_splitncnn_3 1043_splitncnn_2 1046_splitncnn_2 1047 +Convolution Conv_345 1 1 1047 1049 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_83 1 2 1049 1049_splitncnn_0 1049_splitncnn_1 +Concat Concat_347 4 1 1041_splitncnn_2 1043_splitncnn_1 1046_splitncnn_1 1049_splitncnn_1 1050 +Convolution Conv_348 1 1 1050 1052 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_350 5 1 1041_splitncnn_1 1043_splitncnn_0 1046_splitncnn_0 1049_splitncnn_0 1052 1053 +Convolution Conv_351 1 1 1053 1054 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_354 2 1 1054 1041_splitncnn_0 1057 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_357 2 1 1057 1009_splitncnn_0 1060 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_84 1 7 1060 1060_splitncnn_0 1060_splitncnn_1 1060_splitncnn_2 1060_splitncnn_3 1060_splitncnn_4 1060_splitncnn_5 1060_splitncnn_6 +Convolution Conv_358 1 1 1060_splitncnn_6 1062 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_85 1 4 1062 1062_splitncnn_0 1062_splitncnn_1 1062_splitncnn_2 1062_splitncnn_3 +Concat Concat_360 2 1 1060_splitncnn_5 1062_splitncnn_3 1063 +Convolution Conv_361 1 1 1063 1065 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_86 1 3 1065 1065_splitncnn_0 1065_splitncnn_1 1065_splitncnn_2 +Concat Concat_363 3 1 1060_splitncnn_4 1062_splitncnn_2 1065_splitncnn_2 1066 +Convolution Conv_364 1 1 1066 1068 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_87 1 2 1068 1068_splitncnn_0 1068_splitncnn_1 +Concat Concat_366 4 1 1060_splitncnn_3 1062_splitncnn_1 1065_splitncnn_1 1068_splitncnn_1 1069 +Convolution Conv_367 1 1 1069 1071 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_369 5 1 1060_splitncnn_2 1062_splitncnn_0 1065_splitncnn_0 1068_splitncnn_0 1071 1072 +Convolution Conv_370 1 1 1072 1073 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_373 2 1 1073 1060_splitncnn_1 1076 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_88 1 6 1076 1076_splitncnn_0 1076_splitncnn_1 1076_splitncnn_2 1076_splitncnn_3 1076_splitncnn_4 1076_splitncnn_5 +Convolution Conv_374 1 1 1076_splitncnn_5 1078 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_89 1 4 1078 1078_splitncnn_0 1078_splitncnn_1 1078_splitncnn_2 1078_splitncnn_3 +Concat Concat_376 2 1 1076_splitncnn_4 1078_splitncnn_3 1079 +Convolution Conv_377 1 1 1079 1081 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_90 1 3 1081 1081_splitncnn_0 1081_splitncnn_1 1081_splitncnn_2 +Concat Concat_379 3 1 1076_splitncnn_3 1078_splitncnn_2 1081_splitncnn_2 1082 +Convolution Conv_380 1 1 1082 1084 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_91 1 2 1084 1084_splitncnn_0 1084_splitncnn_1 +Concat Concat_382 4 1 1076_splitncnn_2 1078_splitncnn_1 1081_splitncnn_1 1084_splitncnn_1 1085 +Convolution Conv_383 1 1 1085 1087 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_385 5 1 1076_splitncnn_1 1078_splitncnn_0 1081_splitncnn_0 1084_splitncnn_0 1087 1088 +Convolution Conv_386 1 1 1088 1089 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_389 2 1 1089 1076_splitncnn_0 1092 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_92 1 6 1092 1092_splitncnn_0 1092_splitncnn_1 1092_splitncnn_2 1092_splitncnn_3 1092_splitncnn_4 1092_splitncnn_5 +Convolution Conv_390 1 1 1092_splitncnn_5 1094 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_93 1 4 1094 1094_splitncnn_0 1094_splitncnn_1 1094_splitncnn_2 1094_splitncnn_3 +Concat Concat_392 2 1 1092_splitncnn_4 1094_splitncnn_3 1095 +Convolution Conv_393 1 1 1095 1097 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_94 1 3 1097 1097_splitncnn_0 1097_splitncnn_1 1097_splitncnn_2 +Concat Concat_395 3 1 1092_splitncnn_3 1094_splitncnn_2 1097_splitncnn_2 1098 +Convolution Conv_396 1 1 1098 1100 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_95 1 2 1100 1100_splitncnn_0 1100_splitncnn_1 +Concat Concat_398 4 1 1092_splitncnn_2 1094_splitncnn_1 1097_splitncnn_1 1100_splitncnn_1 1101 +Convolution Conv_399 1 1 1101 1103 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_401 5 1 1092_splitncnn_1 1094_splitncnn_0 1097_splitncnn_0 1100_splitncnn_0 1103 1104 +Convolution Conv_402 1 1 1104 1105 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_405 2 1 1105 1092_splitncnn_0 1108 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_408 2 1 1108 1060_splitncnn_0 1111 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_96 1 7 1111 1111_splitncnn_0 1111_splitncnn_1 1111_splitncnn_2 1111_splitncnn_3 1111_splitncnn_4 1111_splitncnn_5 1111_splitncnn_6 +Convolution Conv_409 1 1 1111_splitncnn_6 1113 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_97 1 4 1113 1113_splitncnn_0 1113_splitncnn_1 1113_splitncnn_2 1113_splitncnn_3 +Concat Concat_411 2 1 1111_splitncnn_5 1113_splitncnn_3 1114 +Convolution Conv_412 1 1 1114 1116 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_98 1 3 1116 1116_splitncnn_0 1116_splitncnn_1 1116_splitncnn_2 +Concat Concat_414 3 1 1111_splitncnn_4 1113_splitncnn_2 1116_splitncnn_2 1117 +Convolution Conv_415 1 1 1117 1119 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_99 1 2 1119 1119_splitncnn_0 1119_splitncnn_1 +Concat Concat_417 4 1 1111_splitncnn_3 1113_splitncnn_1 1116_splitncnn_1 1119_splitncnn_1 1120 +Convolution Conv_418 1 1 1120 1122 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_420 5 1 1111_splitncnn_2 1113_splitncnn_0 1116_splitncnn_0 1119_splitncnn_0 1122 1123 +Convolution Conv_421 1 1 1123 1124 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_424 2 1 1124 1111_splitncnn_1 1127 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_100 1 6 1127 1127_splitncnn_0 1127_splitncnn_1 1127_splitncnn_2 1127_splitncnn_3 1127_splitncnn_4 1127_splitncnn_5 +Convolution Conv_425 1 1 1127_splitncnn_5 1129 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_101 1 4 1129 1129_splitncnn_0 1129_splitncnn_1 1129_splitncnn_2 1129_splitncnn_3 +Concat Concat_427 2 1 1127_splitncnn_4 1129_splitncnn_3 1130 +Convolution Conv_428 1 1 1130 1132 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_102 1 3 1132 1132_splitncnn_0 1132_splitncnn_1 1132_splitncnn_2 +Concat Concat_430 3 1 1127_splitncnn_3 1129_splitncnn_2 1132_splitncnn_2 1133 +Convolution Conv_431 1 1 1133 1135 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_103 1 2 1135 1135_splitncnn_0 1135_splitncnn_1 +Concat Concat_433 4 1 1127_splitncnn_2 1129_splitncnn_1 1132_splitncnn_1 1135_splitncnn_1 1136 +Convolution Conv_434 1 1 1136 1138 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_436 5 1 1127_splitncnn_1 1129_splitncnn_0 1132_splitncnn_0 1135_splitncnn_0 1138 1139 +Convolution Conv_437 1 1 1139 1140 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_440 2 1 1140 1127_splitncnn_0 1143 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_104 1 6 1143 1143_splitncnn_0 1143_splitncnn_1 1143_splitncnn_2 1143_splitncnn_3 1143_splitncnn_4 1143_splitncnn_5 +Convolution Conv_441 1 1 1143_splitncnn_5 1145 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_105 1 4 1145 1145_splitncnn_0 1145_splitncnn_1 1145_splitncnn_2 1145_splitncnn_3 +Concat Concat_443 2 1 1143_splitncnn_4 1145_splitncnn_3 1146 +Convolution Conv_444 1 1 1146 1148 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_106 1 3 1148 1148_splitncnn_0 1148_splitncnn_1 1148_splitncnn_2 +Concat Concat_446 3 1 1143_splitncnn_3 1145_splitncnn_2 1148_splitncnn_2 1149 +Convolution Conv_447 1 1 1149 1151 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_107 1 2 1151 1151_splitncnn_0 1151_splitncnn_1 +Concat Concat_449 4 1 1143_splitncnn_2 1145_splitncnn_1 1148_splitncnn_1 1151_splitncnn_1 1152 +Convolution Conv_450 1 1 1152 1154 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_452 5 1 1143_splitncnn_1 1145_splitncnn_0 1148_splitncnn_0 1151_splitncnn_0 1154 1155 +Convolution Conv_453 1 1 1155 1156 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_456 2 1 1156 1143_splitncnn_0 1159 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_459 2 1 1159 1111_splitncnn_0 1162 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_108 1 7 1162 1162_splitncnn_0 1162_splitncnn_1 1162_splitncnn_2 1162_splitncnn_3 1162_splitncnn_4 1162_splitncnn_5 1162_splitncnn_6 +Convolution Conv_460 1 1 1162_splitncnn_6 1164 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_109 1 4 1164 1164_splitncnn_0 1164_splitncnn_1 1164_splitncnn_2 1164_splitncnn_3 +Concat Concat_462 2 1 1162_splitncnn_5 1164_splitncnn_3 1165 +Convolution Conv_463 1 1 1165 1167 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_110 1 3 1167 1167_splitncnn_0 1167_splitncnn_1 1167_splitncnn_2 +Concat Concat_465 3 1 1162_splitncnn_4 1164_splitncnn_2 1167_splitncnn_2 1168 +Convolution Conv_466 1 1 1168 1170 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_111 1 2 1170 1170_splitncnn_0 1170_splitncnn_1 +Concat Concat_468 4 1 1162_splitncnn_3 1164_splitncnn_1 1167_splitncnn_1 1170_splitncnn_1 1171 +Convolution Conv_469 1 1 1171 1173 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_471 5 1 1162_splitncnn_2 1164_splitncnn_0 1167_splitncnn_0 1170_splitncnn_0 1173 1174 +Convolution Conv_472 1 1 1174 1175 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_475 2 1 1175 1162_splitncnn_1 1178 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_112 1 6 1178 1178_splitncnn_0 1178_splitncnn_1 1178_splitncnn_2 1178_splitncnn_3 1178_splitncnn_4 1178_splitncnn_5 +Convolution Conv_476 1 1 1178_splitncnn_5 1180 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_113 1 4 1180 1180_splitncnn_0 1180_splitncnn_1 1180_splitncnn_2 1180_splitncnn_3 +Concat Concat_478 2 1 1178_splitncnn_4 1180_splitncnn_3 1181 +Convolution Conv_479 1 1 1181 1183 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_114 1 3 1183 1183_splitncnn_0 1183_splitncnn_1 1183_splitncnn_2 +Concat Concat_481 3 1 1178_splitncnn_3 1180_splitncnn_2 1183_splitncnn_2 1184 +Convolution Conv_482 1 1 1184 1186 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_115 1 2 1186 1186_splitncnn_0 1186_splitncnn_1 +Concat Concat_484 4 1 1178_splitncnn_2 1180_splitncnn_1 1183_splitncnn_1 1186_splitncnn_1 1187 +Convolution Conv_485 1 1 1187 1189 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_487 5 1 1178_splitncnn_1 1180_splitncnn_0 1183_splitncnn_0 1186_splitncnn_0 1189 1190 +Convolution Conv_488 1 1 1190 1191 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_491 2 1 1191 1178_splitncnn_0 1194 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_116 1 6 1194 1194_splitncnn_0 1194_splitncnn_1 1194_splitncnn_2 1194_splitncnn_3 1194_splitncnn_4 1194_splitncnn_5 +Convolution Conv_492 1 1 1194_splitncnn_5 1196 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_117 1 4 1196 1196_splitncnn_0 1196_splitncnn_1 1196_splitncnn_2 1196_splitncnn_3 +Concat Concat_494 2 1 1194_splitncnn_4 1196_splitncnn_3 1197 +Convolution Conv_495 1 1 1197 1199 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_118 1 3 1199 1199_splitncnn_0 1199_splitncnn_1 1199_splitncnn_2 +Concat Concat_497 3 1 1194_splitncnn_3 1196_splitncnn_2 1199_splitncnn_2 1200 +Convolution Conv_498 1 1 1200 1202 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_119 1 2 1202 1202_splitncnn_0 1202_splitncnn_1 +Concat Concat_500 4 1 1194_splitncnn_2 1196_splitncnn_1 1199_splitncnn_1 1202_splitncnn_1 1203 +Convolution Conv_501 1 1 1203 1205 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_503 5 1 1194_splitncnn_1 1196_splitncnn_0 1199_splitncnn_0 1202_splitncnn_0 1205 1206 +Convolution Conv_504 1 1 1206 1207 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_507 2 1 1207 1194_splitncnn_0 1210 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_510 2 1 1210 1162_splitncnn_0 1213 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_120 1 7 1213 1213_splitncnn_0 1213_splitncnn_1 1213_splitncnn_2 1213_splitncnn_3 1213_splitncnn_4 1213_splitncnn_5 1213_splitncnn_6 +Convolution Conv_511 1 1 1213_splitncnn_6 1215 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_121 1 4 1215 1215_splitncnn_0 1215_splitncnn_1 1215_splitncnn_2 1215_splitncnn_3 +Concat Concat_513 2 1 1213_splitncnn_5 1215_splitncnn_3 1216 +Convolution Conv_514 1 1 1216 1218 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_122 1 3 1218 1218_splitncnn_0 1218_splitncnn_1 1218_splitncnn_2 +Concat Concat_516 3 1 1213_splitncnn_4 1215_splitncnn_2 1218_splitncnn_2 1219 +Convolution Conv_517 1 1 1219 1221 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_123 1 2 1221 1221_splitncnn_0 1221_splitncnn_1 +Concat Concat_519 4 1 1213_splitncnn_3 1215_splitncnn_1 1218_splitncnn_1 1221_splitncnn_1 1222 +Convolution Conv_520 1 1 1222 1224 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_522 5 1 1213_splitncnn_2 1215_splitncnn_0 1218_splitncnn_0 1221_splitncnn_0 1224 1225 +Convolution Conv_523 1 1 1225 1226 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_526 2 1 1226 1213_splitncnn_1 1229 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_124 1 6 1229 1229_splitncnn_0 1229_splitncnn_1 1229_splitncnn_2 1229_splitncnn_3 1229_splitncnn_4 1229_splitncnn_5 +Convolution Conv_527 1 1 1229_splitncnn_5 1231 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_125 1 4 1231 1231_splitncnn_0 1231_splitncnn_1 1231_splitncnn_2 1231_splitncnn_3 +Concat Concat_529 2 1 1229_splitncnn_4 1231_splitncnn_3 1232 +Convolution Conv_530 1 1 1232 1234 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_126 1 3 1234 1234_splitncnn_0 1234_splitncnn_1 1234_splitncnn_2 +Concat Concat_532 3 1 1229_splitncnn_3 1231_splitncnn_2 1234_splitncnn_2 1235 +Convolution Conv_533 1 1 1235 1237 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_127 1 2 1237 1237_splitncnn_0 1237_splitncnn_1 +Concat Concat_535 4 1 1229_splitncnn_2 1231_splitncnn_1 1234_splitncnn_1 1237_splitncnn_1 1238 +Convolution Conv_536 1 1 1238 1240 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_538 5 1 1229_splitncnn_1 1231_splitncnn_0 1234_splitncnn_0 1237_splitncnn_0 1240 1241 +Convolution Conv_539 1 1 1241 1242 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_542 2 1 1242 1229_splitncnn_0 1245 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_128 1 6 1245 1245_splitncnn_0 1245_splitncnn_1 1245_splitncnn_2 1245_splitncnn_3 1245_splitncnn_4 1245_splitncnn_5 +Convolution Conv_543 1 1 1245_splitncnn_5 1247 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_129 1 4 1247 1247_splitncnn_0 1247_splitncnn_1 1247_splitncnn_2 1247_splitncnn_3 +Concat Concat_545 2 1 1245_splitncnn_4 1247_splitncnn_3 1248 +Convolution Conv_546 1 1 1248 1250 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_130 1 3 1250 1250_splitncnn_0 1250_splitncnn_1 1250_splitncnn_2 +Concat Concat_548 3 1 1245_splitncnn_3 1247_splitncnn_2 1250_splitncnn_2 1251 +Convolution Conv_549 1 1 1251 1253 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_131 1 2 1253 1253_splitncnn_0 1253_splitncnn_1 +Concat Concat_551 4 1 1245_splitncnn_2 1247_splitncnn_1 1250_splitncnn_1 1253_splitncnn_1 1254 +Convolution Conv_552 1 1 1254 1256 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_554 5 1 1245_splitncnn_1 1247_splitncnn_0 1250_splitncnn_0 1253_splitncnn_0 1256 1257 +Convolution Conv_555 1 1 1257 1258 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_558 2 1 1258 1245_splitncnn_0 1261 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_561 2 1 1261 1213_splitncnn_0 1264 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_132 1 7 1264 1264_splitncnn_0 1264_splitncnn_1 1264_splitncnn_2 1264_splitncnn_3 1264_splitncnn_4 1264_splitncnn_5 1264_splitncnn_6 +Convolution Conv_562 1 1 1264_splitncnn_6 1266 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_133 1 4 1266 1266_splitncnn_0 1266_splitncnn_1 1266_splitncnn_2 1266_splitncnn_3 +Concat Concat_564 2 1 1264_splitncnn_5 1266_splitncnn_3 1267 +Convolution Conv_565 1 1 1267 1269 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_134 1 3 1269 1269_splitncnn_0 1269_splitncnn_1 1269_splitncnn_2 +Concat Concat_567 3 1 1264_splitncnn_4 1266_splitncnn_2 1269_splitncnn_2 1270 +Convolution Conv_568 1 1 1270 1272 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_135 1 2 1272 1272_splitncnn_0 1272_splitncnn_1 +Concat Concat_570 4 1 1264_splitncnn_3 1266_splitncnn_1 1269_splitncnn_1 1272_splitncnn_1 1273 +Convolution Conv_571 1 1 1273 1275 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_573 5 1 1264_splitncnn_2 1266_splitncnn_0 1269_splitncnn_0 1272_splitncnn_0 1275 1276 +Convolution Conv_574 1 1 1276 1277 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_577 2 1 1277 1264_splitncnn_1 1280 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_136 1 6 1280 1280_splitncnn_0 1280_splitncnn_1 1280_splitncnn_2 1280_splitncnn_3 1280_splitncnn_4 1280_splitncnn_5 +Convolution Conv_578 1 1 1280_splitncnn_5 1282 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_137 1 4 1282 1282_splitncnn_0 1282_splitncnn_1 1282_splitncnn_2 1282_splitncnn_3 +Concat Concat_580 2 1 1280_splitncnn_4 1282_splitncnn_3 1283 +Convolution Conv_581 1 1 1283 1285 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_138 1 3 1285 1285_splitncnn_0 1285_splitncnn_1 1285_splitncnn_2 +Concat Concat_583 3 1 1280_splitncnn_3 1282_splitncnn_2 1285_splitncnn_2 1286 +Convolution Conv_584 1 1 1286 1288 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_139 1 2 1288 1288_splitncnn_0 1288_splitncnn_1 +Concat Concat_586 4 1 1280_splitncnn_2 1282_splitncnn_1 1285_splitncnn_1 1288_splitncnn_1 1289 +Convolution Conv_587 1 1 1289 1291 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_589 5 1 1280_splitncnn_1 1282_splitncnn_0 1285_splitncnn_0 1288_splitncnn_0 1291 1292 +Convolution Conv_590 1 1 1292 1293 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_593 2 1 1293 1280_splitncnn_0 1296 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_140 1 6 1296 1296_splitncnn_0 1296_splitncnn_1 1296_splitncnn_2 1296_splitncnn_3 1296_splitncnn_4 1296_splitncnn_5 +Convolution Conv_594 1 1 1296_splitncnn_5 1298 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_141 1 4 1298 1298_splitncnn_0 1298_splitncnn_1 1298_splitncnn_2 1298_splitncnn_3 +Concat Concat_596 2 1 1296_splitncnn_4 1298_splitncnn_3 1299 +Convolution Conv_597 1 1 1299 1301 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_142 1 3 1301 1301_splitncnn_0 1301_splitncnn_1 1301_splitncnn_2 +Concat Concat_599 3 1 1296_splitncnn_3 1298_splitncnn_2 1301_splitncnn_2 1302 +Convolution Conv_600 1 1 1302 1304 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_143 1 2 1304 1304_splitncnn_0 1304_splitncnn_1 +Concat Concat_602 4 1 1296_splitncnn_2 1298_splitncnn_1 1301_splitncnn_1 1304_splitncnn_1 1305 +Convolution Conv_603 1 1 1305 1307 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_605 5 1 1296_splitncnn_1 1298_splitncnn_0 1301_splitncnn_0 1304_splitncnn_0 1307 1308 +Convolution Conv_606 1 1 1308 1309 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_609 2 1 1309 1296_splitncnn_0 1312 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_612 2 1 1312 1264_splitncnn_0 1315 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_144 1 7 1315 1315_splitncnn_0 1315_splitncnn_1 1315_splitncnn_2 1315_splitncnn_3 1315_splitncnn_4 1315_splitncnn_5 1315_splitncnn_6 +Convolution Conv_613 1 1 1315_splitncnn_6 1317 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_145 1 4 1317 1317_splitncnn_0 1317_splitncnn_1 1317_splitncnn_2 1317_splitncnn_3 +Concat Concat_615 2 1 1315_splitncnn_5 1317_splitncnn_3 1318 +Convolution Conv_616 1 1 1318 1320 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_146 1 3 1320 1320_splitncnn_0 1320_splitncnn_1 1320_splitncnn_2 +Concat Concat_618 3 1 1315_splitncnn_4 1317_splitncnn_2 1320_splitncnn_2 1321 +Convolution Conv_619 1 1 1321 1323 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_147 1 2 1323 1323_splitncnn_0 1323_splitncnn_1 +Concat Concat_621 4 1 1315_splitncnn_3 1317_splitncnn_1 1320_splitncnn_1 1323_splitncnn_1 1324 +Convolution Conv_622 1 1 1324 1326 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_624 5 1 1315_splitncnn_2 1317_splitncnn_0 1320_splitncnn_0 1323_splitncnn_0 1326 1327 +Convolution Conv_625 1 1 1327 1328 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_628 2 1 1328 1315_splitncnn_1 1331 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_148 1 6 1331 1331_splitncnn_0 1331_splitncnn_1 1331_splitncnn_2 1331_splitncnn_3 1331_splitncnn_4 1331_splitncnn_5 +Convolution Conv_629 1 1 1331_splitncnn_5 1333 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_149 1 4 1333 1333_splitncnn_0 1333_splitncnn_1 1333_splitncnn_2 1333_splitncnn_3 +Concat Concat_631 2 1 1331_splitncnn_4 1333_splitncnn_3 1334 +Convolution Conv_632 1 1 1334 1336 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_150 1 3 1336 1336_splitncnn_0 1336_splitncnn_1 1336_splitncnn_2 +Concat Concat_634 3 1 1331_splitncnn_3 1333_splitncnn_2 1336_splitncnn_2 1337 +Convolution Conv_635 1 1 1337 1339 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_151 1 2 1339 1339_splitncnn_0 1339_splitncnn_1 +Concat Concat_637 4 1 1331_splitncnn_2 1333_splitncnn_1 1336_splitncnn_1 1339_splitncnn_1 1340 +Convolution Conv_638 1 1 1340 1342 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_640 5 1 1331_splitncnn_1 1333_splitncnn_0 1336_splitncnn_0 1339_splitncnn_0 1342 1343 +Convolution Conv_641 1 1 1343 1344 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_644 2 1 1344 1331_splitncnn_0 1347 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_152 1 6 1347 1347_splitncnn_0 1347_splitncnn_1 1347_splitncnn_2 1347_splitncnn_3 1347_splitncnn_4 1347_splitncnn_5 +Convolution Conv_645 1 1 1347_splitncnn_5 1349 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_153 1 4 1349 1349_splitncnn_0 1349_splitncnn_1 1349_splitncnn_2 1349_splitncnn_3 +Concat Concat_647 2 1 1347_splitncnn_4 1349_splitncnn_3 1350 +Convolution Conv_648 1 1 1350 1352 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_154 1 3 1352 1352_splitncnn_0 1352_splitncnn_1 1352_splitncnn_2 +Concat Concat_650 3 1 1347_splitncnn_3 1349_splitncnn_2 1352_splitncnn_2 1353 +Convolution Conv_651 1 1 1353 1355 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_155 1 2 1355 1355_splitncnn_0 1355_splitncnn_1 +Concat Concat_653 4 1 1347_splitncnn_2 1349_splitncnn_1 1352_splitncnn_1 1355_splitncnn_1 1356 +Convolution Conv_654 1 1 1356 1358 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_656 5 1 1347_splitncnn_1 1349_splitncnn_0 1352_splitncnn_0 1355_splitncnn_0 1358 1359 +Convolution Conv_657 1 1 1359 1360 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_660 2 1 1360 1347_splitncnn_0 1363 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_663 2 1 1363 1315_splitncnn_0 1366 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_156 1 7 1366 1366_splitncnn_0 1366_splitncnn_1 1366_splitncnn_2 1366_splitncnn_3 1366_splitncnn_4 1366_splitncnn_5 1366_splitncnn_6 +Convolution Conv_664 1 1 1366_splitncnn_6 1368 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_157 1 4 1368 1368_splitncnn_0 1368_splitncnn_1 1368_splitncnn_2 1368_splitncnn_3 +Concat Concat_666 2 1 1366_splitncnn_5 1368_splitncnn_3 1369 +Convolution Conv_667 1 1 1369 1371 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_158 1 3 1371 1371_splitncnn_0 1371_splitncnn_1 1371_splitncnn_2 +Concat Concat_669 3 1 1366_splitncnn_4 1368_splitncnn_2 1371_splitncnn_2 1372 +Convolution Conv_670 1 1 1372 1374 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_159 1 2 1374 1374_splitncnn_0 1374_splitncnn_1 +Concat Concat_672 4 1 1366_splitncnn_3 1368_splitncnn_1 1371_splitncnn_1 1374_splitncnn_1 1375 +Convolution Conv_673 1 1 1375 1377 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_675 5 1 1366_splitncnn_2 1368_splitncnn_0 1371_splitncnn_0 1374_splitncnn_0 1377 1378 +Convolution Conv_676 1 1 1378 1379 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_679 2 1 1379 1366_splitncnn_1 1382 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_160 1 6 1382 1382_splitncnn_0 1382_splitncnn_1 1382_splitncnn_2 1382_splitncnn_3 1382_splitncnn_4 1382_splitncnn_5 +Convolution Conv_680 1 1 1382_splitncnn_5 1384 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_161 1 4 1384 1384_splitncnn_0 1384_splitncnn_1 1384_splitncnn_2 1384_splitncnn_3 +Concat Concat_682 2 1 1382_splitncnn_4 1384_splitncnn_3 1385 +Convolution Conv_683 1 1 1385 1387 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_162 1 3 1387 1387_splitncnn_0 1387_splitncnn_1 1387_splitncnn_2 +Concat Concat_685 3 1 1382_splitncnn_3 1384_splitncnn_2 1387_splitncnn_2 1388 +Convolution Conv_686 1 1 1388 1390 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_163 1 2 1390 1390_splitncnn_0 1390_splitncnn_1 +Concat Concat_688 4 1 1382_splitncnn_2 1384_splitncnn_1 1387_splitncnn_1 1390_splitncnn_1 1391 +Convolution Conv_689 1 1 1391 1393 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_691 5 1 1382_splitncnn_1 1384_splitncnn_0 1387_splitncnn_0 1390_splitncnn_0 1393 1394 +Convolution Conv_692 1 1 1394 1395 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_695 2 1 1395 1382_splitncnn_0 1398 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_164 1 6 1398 1398_splitncnn_0 1398_splitncnn_1 1398_splitncnn_2 1398_splitncnn_3 1398_splitncnn_4 1398_splitncnn_5 +Convolution Conv_696 1 1 1398_splitncnn_5 1400 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_165 1 4 1400 1400_splitncnn_0 1400_splitncnn_1 1400_splitncnn_2 1400_splitncnn_3 +Concat Concat_698 2 1 1398_splitncnn_4 1400_splitncnn_3 1401 +Convolution Conv_699 1 1 1401 1403 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_166 1 3 1403 1403_splitncnn_0 1403_splitncnn_1 1403_splitncnn_2 +Concat Concat_701 3 1 1398_splitncnn_3 1400_splitncnn_2 1403_splitncnn_2 1404 +Convolution Conv_702 1 1 1404 1406 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_167 1 2 1406 1406_splitncnn_0 1406_splitncnn_1 +Concat Concat_704 4 1 1398_splitncnn_2 1400_splitncnn_1 1403_splitncnn_1 1406_splitncnn_1 1407 +Convolution Conv_705 1 1 1407 1409 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_707 5 1 1398_splitncnn_1 1400_splitncnn_0 1403_splitncnn_0 1406_splitncnn_0 1409 1410 +Convolution Conv_708 1 1 1410 1411 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_711 2 1 1411 1398_splitncnn_0 1414 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_714 2 1 1414 1366_splitncnn_0 1417 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_168 1 7 1417 1417_splitncnn_0 1417_splitncnn_1 1417_splitncnn_2 1417_splitncnn_3 1417_splitncnn_4 1417_splitncnn_5 1417_splitncnn_6 +Convolution Conv_715 1 1 1417_splitncnn_6 1419 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_169 1 4 1419 1419_splitncnn_0 1419_splitncnn_1 1419_splitncnn_2 1419_splitncnn_3 +Concat Concat_717 2 1 1417_splitncnn_5 1419_splitncnn_3 1420 +Convolution Conv_718 1 1 1420 1422 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_170 1 3 1422 1422_splitncnn_0 1422_splitncnn_1 1422_splitncnn_2 +Concat Concat_720 3 1 1417_splitncnn_4 1419_splitncnn_2 1422_splitncnn_2 1423 +Convolution Conv_721 1 1 1423 1425 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_171 1 2 1425 1425_splitncnn_0 1425_splitncnn_1 +Concat Concat_723 4 1 1417_splitncnn_3 1419_splitncnn_1 1422_splitncnn_1 1425_splitncnn_1 1426 +Convolution Conv_724 1 1 1426 1428 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_726 5 1 1417_splitncnn_2 1419_splitncnn_0 1422_splitncnn_0 1425_splitncnn_0 1428 1429 +Convolution Conv_727 1 1 1429 1430 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_730 2 1 1430 1417_splitncnn_1 1433 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_172 1 6 1433 1433_splitncnn_0 1433_splitncnn_1 1433_splitncnn_2 1433_splitncnn_3 1433_splitncnn_4 1433_splitncnn_5 +Convolution Conv_731 1 1 1433_splitncnn_5 1435 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_173 1 4 1435 1435_splitncnn_0 1435_splitncnn_1 1435_splitncnn_2 1435_splitncnn_3 +Concat Concat_733 2 1 1433_splitncnn_4 1435_splitncnn_3 1436 +Convolution Conv_734 1 1 1436 1438 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_174 1 3 1438 1438_splitncnn_0 1438_splitncnn_1 1438_splitncnn_2 +Concat Concat_736 3 1 1433_splitncnn_3 1435_splitncnn_2 1438_splitncnn_2 1439 +Convolution Conv_737 1 1 1439 1441 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_175 1 2 1441 1441_splitncnn_0 1441_splitncnn_1 +Concat Concat_739 4 1 1433_splitncnn_2 1435_splitncnn_1 1438_splitncnn_1 1441_splitncnn_1 1442 +Convolution Conv_740 1 1 1442 1444 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_742 5 1 1433_splitncnn_1 1435_splitncnn_0 1438_splitncnn_0 1441_splitncnn_0 1444 1445 +Convolution Conv_743 1 1 1445 1446 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_746 2 1 1446 1433_splitncnn_0 1449 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_176 1 6 1449 1449_splitncnn_0 1449_splitncnn_1 1449_splitncnn_2 1449_splitncnn_3 1449_splitncnn_4 1449_splitncnn_5 +Convolution Conv_747 1 1 1449_splitncnn_5 1451 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_177 1 4 1451 1451_splitncnn_0 1451_splitncnn_1 1451_splitncnn_2 1451_splitncnn_3 +Concat Concat_749 2 1 1449_splitncnn_4 1451_splitncnn_3 1452 +Convolution Conv_750 1 1 1452 1454 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_178 1 3 1454 1454_splitncnn_0 1454_splitncnn_1 1454_splitncnn_2 +Concat Concat_752 3 1 1449_splitncnn_3 1451_splitncnn_2 1454_splitncnn_2 1455 +Convolution Conv_753 1 1 1455 1457 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_179 1 2 1457 1457_splitncnn_0 1457_splitncnn_1 +Concat Concat_755 4 1 1449_splitncnn_2 1451_splitncnn_1 1454_splitncnn_1 1457_splitncnn_1 1458 +Convolution Conv_756 1 1 1458 1460 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_758 5 1 1449_splitncnn_1 1451_splitncnn_0 1454_splitncnn_0 1457_splitncnn_0 1460 1461 +Convolution Conv_759 1 1 1461 1462 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_762 2 1 1462 1449_splitncnn_0 1465 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_765 2 1 1465 1417_splitncnn_0 1468 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_180 1 7 1468 1468_splitncnn_0 1468_splitncnn_1 1468_splitncnn_2 1468_splitncnn_3 1468_splitncnn_4 1468_splitncnn_5 1468_splitncnn_6 +Convolution Conv_766 1 1 1468_splitncnn_6 1470 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_181 1 4 1470 1470_splitncnn_0 1470_splitncnn_1 1470_splitncnn_2 1470_splitncnn_3 +Concat Concat_768 2 1 1468_splitncnn_5 1470_splitncnn_3 1471 +Convolution Conv_769 1 1 1471 1473 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_182 1 3 1473 1473_splitncnn_0 1473_splitncnn_1 1473_splitncnn_2 +Concat Concat_771 3 1 1468_splitncnn_4 1470_splitncnn_2 1473_splitncnn_2 1474 +Convolution Conv_772 1 1 1474 1476 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_183 1 2 1476 1476_splitncnn_0 1476_splitncnn_1 +Concat Concat_774 4 1 1468_splitncnn_3 1470_splitncnn_1 1473_splitncnn_1 1476_splitncnn_1 1477 +Convolution Conv_775 1 1 1477 1479 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_777 5 1 1468_splitncnn_2 1470_splitncnn_0 1473_splitncnn_0 1476_splitncnn_0 1479 1480 +Convolution Conv_778 1 1 1480 1481 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_781 2 1 1481 1468_splitncnn_1 1484 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_184 1 6 1484 1484_splitncnn_0 1484_splitncnn_1 1484_splitncnn_2 1484_splitncnn_3 1484_splitncnn_4 1484_splitncnn_5 +Convolution Conv_782 1 1 1484_splitncnn_5 1486 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_185 1 4 1486 1486_splitncnn_0 1486_splitncnn_1 1486_splitncnn_2 1486_splitncnn_3 +Concat Concat_784 2 1 1484_splitncnn_4 1486_splitncnn_3 1487 +Convolution Conv_785 1 1 1487 1489 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_186 1 3 1489 1489_splitncnn_0 1489_splitncnn_1 1489_splitncnn_2 +Concat Concat_787 3 1 1484_splitncnn_3 1486_splitncnn_2 1489_splitncnn_2 1490 +Convolution Conv_788 1 1 1490 1492 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_187 1 2 1492 1492_splitncnn_0 1492_splitncnn_1 +Concat Concat_790 4 1 1484_splitncnn_2 1486_splitncnn_1 1489_splitncnn_1 1492_splitncnn_1 1493 +Convolution Conv_791 1 1 1493 1495 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_793 5 1 1484_splitncnn_1 1486_splitncnn_0 1489_splitncnn_0 1492_splitncnn_0 1495 1496 +Convolution Conv_794 1 1 1496 1497 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_797 2 1 1497 1484_splitncnn_0 1500 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_188 1 6 1500 1500_splitncnn_0 1500_splitncnn_1 1500_splitncnn_2 1500_splitncnn_3 1500_splitncnn_4 1500_splitncnn_5 +Convolution Conv_798 1 1 1500_splitncnn_5 1502 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_189 1 4 1502 1502_splitncnn_0 1502_splitncnn_1 1502_splitncnn_2 1502_splitncnn_3 +Concat Concat_800 2 1 1500_splitncnn_4 1502_splitncnn_3 1503 +Convolution Conv_801 1 1 1503 1505 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_190 1 3 1505 1505_splitncnn_0 1505_splitncnn_1 1505_splitncnn_2 +Concat Concat_803 3 1 1500_splitncnn_3 1502_splitncnn_2 1505_splitncnn_2 1506 +Convolution Conv_804 1 1 1506 1508 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_191 1 2 1508 1508_splitncnn_0 1508_splitncnn_1 +Concat Concat_806 4 1 1500_splitncnn_2 1502_splitncnn_1 1505_splitncnn_1 1508_splitncnn_1 1509 +Convolution Conv_807 1 1 1509 1511 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_809 5 1 1500_splitncnn_1 1502_splitncnn_0 1505_splitncnn_0 1508_splitncnn_0 1511 1512 +Convolution Conv_810 1 1 1512 1513 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_813 2 1 1513 1500_splitncnn_0 1516 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_816 2 1 1516 1468_splitncnn_0 1519 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_192 1 7 1519 1519_splitncnn_0 1519_splitncnn_1 1519_splitncnn_2 1519_splitncnn_3 1519_splitncnn_4 1519_splitncnn_5 1519_splitncnn_6 +Convolution Conv_817 1 1 1519_splitncnn_6 1521 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_193 1 4 1521 1521_splitncnn_0 1521_splitncnn_1 1521_splitncnn_2 1521_splitncnn_3 +Concat Concat_819 2 1 1519_splitncnn_5 1521_splitncnn_3 1522 +Convolution Conv_820 1 1 1522 1524 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_194 1 3 1524 1524_splitncnn_0 1524_splitncnn_1 1524_splitncnn_2 +Concat Concat_822 3 1 1519_splitncnn_4 1521_splitncnn_2 1524_splitncnn_2 1525 +Convolution Conv_823 1 1 1525 1527 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_195 1 2 1527 1527_splitncnn_0 1527_splitncnn_1 +Concat Concat_825 4 1 1519_splitncnn_3 1521_splitncnn_1 1524_splitncnn_1 1527_splitncnn_1 1528 +Convolution Conv_826 1 1 1528 1530 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_828 5 1 1519_splitncnn_2 1521_splitncnn_0 1524_splitncnn_0 1527_splitncnn_0 1530 1531 +Convolution Conv_829 1 1 1531 1532 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_832 2 1 1532 1519_splitncnn_1 1535 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_196 1 6 1535 1535_splitncnn_0 1535_splitncnn_1 1535_splitncnn_2 1535_splitncnn_3 1535_splitncnn_4 1535_splitncnn_5 +Convolution Conv_833 1 1 1535_splitncnn_5 1537 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_197 1 4 1537 1537_splitncnn_0 1537_splitncnn_1 1537_splitncnn_2 1537_splitncnn_3 +Concat Concat_835 2 1 1535_splitncnn_4 1537_splitncnn_3 1538 +Convolution Conv_836 1 1 1538 1540 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_198 1 3 1540 1540_splitncnn_0 1540_splitncnn_1 1540_splitncnn_2 +Concat Concat_838 3 1 1535_splitncnn_3 1537_splitncnn_2 1540_splitncnn_2 1541 +Convolution Conv_839 1 1 1541 1543 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_199 1 2 1543 1543_splitncnn_0 1543_splitncnn_1 +Concat Concat_841 4 1 1535_splitncnn_2 1537_splitncnn_1 1540_splitncnn_1 1543_splitncnn_1 1544 +Convolution Conv_842 1 1 1544 1546 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_844 5 1 1535_splitncnn_1 1537_splitncnn_0 1540_splitncnn_0 1543_splitncnn_0 1546 1547 +Convolution Conv_845 1 1 1547 1548 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_848 2 1 1548 1535_splitncnn_0 1551 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_200 1 6 1551 1551_splitncnn_0 1551_splitncnn_1 1551_splitncnn_2 1551_splitncnn_3 1551_splitncnn_4 1551_splitncnn_5 +Convolution Conv_849 1 1 1551_splitncnn_5 1553 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_201 1 4 1553 1553_splitncnn_0 1553_splitncnn_1 1553_splitncnn_2 1553_splitncnn_3 +Concat Concat_851 2 1 1551_splitncnn_4 1553_splitncnn_3 1554 +Convolution Conv_852 1 1 1554 1556 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_202 1 3 1556 1556_splitncnn_0 1556_splitncnn_1 1556_splitncnn_2 +Concat Concat_854 3 1 1551_splitncnn_3 1553_splitncnn_2 1556_splitncnn_2 1557 +Convolution Conv_855 1 1 1557 1559 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_203 1 2 1559 1559_splitncnn_0 1559_splitncnn_1 +Concat Concat_857 4 1 1551_splitncnn_2 1553_splitncnn_1 1556_splitncnn_1 1559_splitncnn_1 1560 +Convolution Conv_858 1 1 1560 1562 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_860 5 1 1551_splitncnn_1 1553_splitncnn_0 1556_splitncnn_0 1559_splitncnn_0 1562 1563 +Convolution Conv_861 1 1 1563 1564 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_864 2 1 1564 1551_splitncnn_0 1567 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_867 2 1 1567 1519_splitncnn_0 1570 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_204 1 7 1570 1570_splitncnn_0 1570_splitncnn_1 1570_splitncnn_2 1570_splitncnn_3 1570_splitncnn_4 1570_splitncnn_5 1570_splitncnn_6 +Convolution Conv_868 1 1 1570_splitncnn_6 1572 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_205 1 4 1572 1572_splitncnn_0 1572_splitncnn_1 1572_splitncnn_2 1572_splitncnn_3 +Concat Concat_870 2 1 1570_splitncnn_5 1572_splitncnn_3 1573 +Convolution Conv_871 1 1 1573 1575 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_206 1 3 1575 1575_splitncnn_0 1575_splitncnn_1 1575_splitncnn_2 +Concat Concat_873 3 1 1570_splitncnn_4 1572_splitncnn_2 1575_splitncnn_2 1576 +Convolution Conv_874 1 1 1576 1578 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_207 1 2 1578 1578_splitncnn_0 1578_splitncnn_1 +Concat Concat_876 4 1 1570_splitncnn_3 1572_splitncnn_1 1575_splitncnn_1 1578_splitncnn_1 1579 +Convolution Conv_877 1 1 1579 1581 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_879 5 1 1570_splitncnn_2 1572_splitncnn_0 1575_splitncnn_0 1578_splitncnn_0 1581 1582 +Convolution Conv_880 1 1 1582 1583 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_883 2 1 1583 1570_splitncnn_1 1586 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_208 1 6 1586 1586_splitncnn_0 1586_splitncnn_1 1586_splitncnn_2 1586_splitncnn_3 1586_splitncnn_4 1586_splitncnn_5 +Convolution Conv_884 1 1 1586_splitncnn_5 1588 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_209 1 4 1588 1588_splitncnn_0 1588_splitncnn_1 1588_splitncnn_2 1588_splitncnn_3 +Concat Concat_886 2 1 1586_splitncnn_4 1588_splitncnn_3 1589 +Convolution Conv_887 1 1 1589 1591 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_210 1 3 1591 1591_splitncnn_0 1591_splitncnn_1 1591_splitncnn_2 +Concat Concat_889 3 1 1586_splitncnn_3 1588_splitncnn_2 1591_splitncnn_2 1592 +Convolution Conv_890 1 1 1592 1594 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_211 1 2 1594 1594_splitncnn_0 1594_splitncnn_1 +Concat Concat_892 4 1 1586_splitncnn_2 1588_splitncnn_1 1591_splitncnn_1 1594_splitncnn_1 1595 +Convolution Conv_893 1 1 1595 1597 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_895 5 1 1586_splitncnn_1 1588_splitncnn_0 1591_splitncnn_0 1594_splitncnn_0 1597 1598 +Convolution Conv_896 1 1 1598 1599 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_899 2 1 1599 1586_splitncnn_0 1602 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_212 1 6 1602 1602_splitncnn_0 1602_splitncnn_1 1602_splitncnn_2 1602_splitncnn_3 1602_splitncnn_4 1602_splitncnn_5 +Convolution Conv_900 1 1 1602_splitncnn_5 1604 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_213 1 4 1604 1604_splitncnn_0 1604_splitncnn_1 1604_splitncnn_2 1604_splitncnn_3 +Concat Concat_902 2 1 1602_splitncnn_4 1604_splitncnn_3 1605 +Convolution Conv_903 1 1 1605 1607 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_214 1 3 1607 1607_splitncnn_0 1607_splitncnn_1 1607_splitncnn_2 +Concat Concat_905 3 1 1602_splitncnn_3 1604_splitncnn_2 1607_splitncnn_2 1608 +Convolution Conv_906 1 1 1608 1610 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_215 1 2 1610 1610_splitncnn_0 1610_splitncnn_1 +Concat Concat_908 4 1 1602_splitncnn_2 1604_splitncnn_1 1607_splitncnn_1 1610_splitncnn_1 1611 +Convolution Conv_909 1 1 1611 1613 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_911 5 1 1602_splitncnn_1 1604_splitncnn_0 1607_splitncnn_0 1610_splitncnn_0 1613 1614 +Convolution Conv_912 1 1 1614 1615 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_915 2 1 1615 1602_splitncnn_0 1618 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_918 2 1 1618 1570_splitncnn_0 1621 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_216 1 7 1621 1621_splitncnn_0 1621_splitncnn_1 1621_splitncnn_2 1621_splitncnn_3 1621_splitncnn_4 1621_splitncnn_5 1621_splitncnn_6 +Convolution Conv_919 1 1 1621_splitncnn_6 1623 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_217 1 4 1623 1623_splitncnn_0 1623_splitncnn_1 1623_splitncnn_2 1623_splitncnn_3 +Concat Concat_921 2 1 1621_splitncnn_5 1623_splitncnn_3 1624 +Convolution Conv_922 1 1 1624 1626 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_218 1 3 1626 1626_splitncnn_0 1626_splitncnn_1 1626_splitncnn_2 +Concat Concat_924 3 1 1621_splitncnn_4 1623_splitncnn_2 1626_splitncnn_2 1627 +Convolution Conv_925 1 1 1627 1629 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_219 1 2 1629 1629_splitncnn_0 1629_splitncnn_1 +Concat Concat_927 4 1 1621_splitncnn_3 1623_splitncnn_1 1626_splitncnn_1 1629_splitncnn_1 1630 +Convolution Conv_928 1 1 1630 1632 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_930 5 1 1621_splitncnn_2 1623_splitncnn_0 1626_splitncnn_0 1629_splitncnn_0 1632 1633 +Convolution Conv_931 1 1 1633 1634 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_934 2 1 1634 1621_splitncnn_1 1637 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_220 1 6 1637 1637_splitncnn_0 1637_splitncnn_1 1637_splitncnn_2 1637_splitncnn_3 1637_splitncnn_4 1637_splitncnn_5 +Convolution Conv_935 1 1 1637_splitncnn_5 1639 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_221 1 4 1639 1639_splitncnn_0 1639_splitncnn_1 1639_splitncnn_2 1639_splitncnn_3 +Concat Concat_937 2 1 1637_splitncnn_4 1639_splitncnn_3 1640 +Convolution Conv_938 1 1 1640 1642 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_222 1 3 1642 1642_splitncnn_0 1642_splitncnn_1 1642_splitncnn_2 +Concat Concat_940 3 1 1637_splitncnn_3 1639_splitncnn_2 1642_splitncnn_2 1643 +Convolution Conv_941 1 1 1643 1645 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_223 1 2 1645 1645_splitncnn_0 1645_splitncnn_1 +Concat Concat_943 4 1 1637_splitncnn_2 1639_splitncnn_1 1642_splitncnn_1 1645_splitncnn_1 1646 +Convolution Conv_944 1 1 1646 1648 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_946 5 1 1637_splitncnn_1 1639_splitncnn_0 1642_splitncnn_0 1645_splitncnn_0 1648 1649 +Convolution Conv_947 1 1 1649 1650 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_950 2 1 1650 1637_splitncnn_0 1653 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_224 1 6 1653 1653_splitncnn_0 1653_splitncnn_1 1653_splitncnn_2 1653_splitncnn_3 1653_splitncnn_4 1653_splitncnn_5 +Convolution Conv_951 1 1 1653_splitncnn_5 1655 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_225 1 4 1655 1655_splitncnn_0 1655_splitncnn_1 1655_splitncnn_2 1655_splitncnn_3 +Concat Concat_953 2 1 1653_splitncnn_4 1655_splitncnn_3 1656 +Convolution Conv_954 1 1 1656 1658 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_226 1 3 1658 1658_splitncnn_0 1658_splitncnn_1 1658_splitncnn_2 +Concat Concat_956 3 1 1653_splitncnn_3 1655_splitncnn_2 1658_splitncnn_2 1659 +Convolution Conv_957 1 1 1659 1661 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_227 1 2 1661 1661_splitncnn_0 1661_splitncnn_1 +Concat Concat_959 4 1 1653_splitncnn_2 1655_splitncnn_1 1658_splitncnn_1 1661_splitncnn_1 1662 +Convolution Conv_960 1 1 1662 1664 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_962 5 1 1653_splitncnn_1 1655_splitncnn_0 1658_splitncnn_0 1661_splitncnn_0 1664 1665 +Convolution Conv_963 1 1 1665 1666 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_966 2 1 1666 1653_splitncnn_0 1669 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_969 2 1 1669 1621_splitncnn_0 1672 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_228 1 7 1672 1672_splitncnn_0 1672_splitncnn_1 1672_splitncnn_2 1672_splitncnn_3 1672_splitncnn_4 1672_splitncnn_5 1672_splitncnn_6 +Convolution Conv_970 1 1 1672_splitncnn_6 1674 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_229 1 4 1674 1674_splitncnn_0 1674_splitncnn_1 1674_splitncnn_2 1674_splitncnn_3 +Concat Concat_972 2 1 1672_splitncnn_5 1674_splitncnn_3 1675 +Convolution Conv_973 1 1 1675 1677 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_230 1 3 1677 1677_splitncnn_0 1677_splitncnn_1 1677_splitncnn_2 +Concat Concat_975 3 1 1672_splitncnn_4 1674_splitncnn_2 1677_splitncnn_2 1678 +Convolution Conv_976 1 1 1678 1680 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_231 1 2 1680 1680_splitncnn_0 1680_splitncnn_1 +Concat Concat_978 4 1 1672_splitncnn_3 1674_splitncnn_1 1677_splitncnn_1 1680_splitncnn_1 1681 +Convolution Conv_979 1 1 1681 1683 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_981 5 1 1672_splitncnn_2 1674_splitncnn_0 1677_splitncnn_0 1680_splitncnn_0 1683 1684 +Convolution Conv_982 1 1 1684 1685 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_985 2 1 1685 1672_splitncnn_1 1688 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_232 1 6 1688 1688_splitncnn_0 1688_splitncnn_1 1688_splitncnn_2 1688_splitncnn_3 1688_splitncnn_4 1688_splitncnn_5 +Convolution Conv_986 1 1 1688_splitncnn_5 1690 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_233 1 4 1690 1690_splitncnn_0 1690_splitncnn_1 1690_splitncnn_2 1690_splitncnn_3 +Concat Concat_988 2 1 1688_splitncnn_4 1690_splitncnn_3 1691 +Convolution Conv_989 1 1 1691 1693 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_234 1 3 1693 1693_splitncnn_0 1693_splitncnn_1 1693_splitncnn_2 +Concat Concat_991 3 1 1688_splitncnn_3 1690_splitncnn_2 1693_splitncnn_2 1694 +Convolution Conv_992 1 1 1694 1696 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_235 1 2 1696 1696_splitncnn_0 1696_splitncnn_1 +Concat Concat_994 4 1 1688_splitncnn_2 1690_splitncnn_1 1693_splitncnn_1 1696_splitncnn_1 1697 +Convolution Conv_995 1 1 1697 1699 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_997 5 1 1688_splitncnn_1 1690_splitncnn_0 1693_splitncnn_0 1696_splitncnn_0 1699 1700 +Convolution Conv_998 1 1 1700 1701 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1001 2 1 1701 1688_splitncnn_0 1704 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_236 1 6 1704 1704_splitncnn_0 1704_splitncnn_1 1704_splitncnn_2 1704_splitncnn_3 1704_splitncnn_4 1704_splitncnn_5 +Convolution Conv_1002 1 1 1704_splitncnn_5 1706 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_237 1 4 1706 1706_splitncnn_0 1706_splitncnn_1 1706_splitncnn_2 1706_splitncnn_3 +Concat Concat_1004 2 1 1704_splitncnn_4 1706_splitncnn_3 1707 +Convolution Conv_1005 1 1 1707 1709 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_238 1 3 1709 1709_splitncnn_0 1709_splitncnn_1 1709_splitncnn_2 +Concat Concat_1007 3 1 1704_splitncnn_3 1706_splitncnn_2 1709_splitncnn_2 1710 +Convolution Conv_1008 1 1 1710 1712 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_239 1 2 1712 1712_splitncnn_0 1712_splitncnn_1 +Concat Concat_1010 4 1 1704_splitncnn_2 1706_splitncnn_1 1709_splitncnn_1 1712_splitncnn_1 1713 +Convolution Conv_1011 1 1 1713 1715 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1013 5 1 1704_splitncnn_1 1706_splitncnn_0 1709_splitncnn_0 1712_splitncnn_0 1715 1716 +Convolution Conv_1014 1 1 1716 1717 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1017 2 1 1717 1704_splitncnn_0 1720 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_1020 2 1 1720 1672_splitncnn_0 1723 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_240 1 7 1723 1723_splitncnn_0 1723_splitncnn_1 1723_splitncnn_2 1723_splitncnn_3 1723_splitncnn_4 1723_splitncnn_5 1723_splitncnn_6 +Convolution Conv_1021 1 1 1723_splitncnn_6 1725 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_241 1 4 1725 1725_splitncnn_0 1725_splitncnn_1 1725_splitncnn_2 1725_splitncnn_3 +Concat Concat_1023 2 1 1723_splitncnn_5 1725_splitncnn_3 1726 +Convolution Conv_1024 1 1 1726 1728 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_242 1 3 1728 1728_splitncnn_0 1728_splitncnn_1 1728_splitncnn_2 +Concat Concat_1026 3 1 1723_splitncnn_4 1725_splitncnn_2 1728_splitncnn_2 1729 +Convolution Conv_1027 1 1 1729 1731 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_243 1 2 1731 1731_splitncnn_0 1731_splitncnn_1 +Concat Concat_1029 4 1 1723_splitncnn_3 1725_splitncnn_1 1728_splitncnn_1 1731_splitncnn_1 1732 +Convolution Conv_1030 1 1 1732 1734 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1032 5 1 1723_splitncnn_2 1725_splitncnn_0 1728_splitncnn_0 1731_splitncnn_0 1734 1735 +Convolution Conv_1033 1 1 1735 1736 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1036 2 1 1736 1723_splitncnn_1 1739 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_244 1 6 1739 1739_splitncnn_0 1739_splitncnn_1 1739_splitncnn_2 1739_splitncnn_3 1739_splitncnn_4 1739_splitncnn_5 +Convolution Conv_1037 1 1 1739_splitncnn_5 1741 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_245 1 4 1741 1741_splitncnn_0 1741_splitncnn_1 1741_splitncnn_2 1741_splitncnn_3 +Concat Concat_1039 2 1 1739_splitncnn_4 1741_splitncnn_3 1742 +Convolution Conv_1040 1 1 1742 1744 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_246 1 3 1744 1744_splitncnn_0 1744_splitncnn_1 1744_splitncnn_2 +Concat Concat_1042 3 1 1739_splitncnn_3 1741_splitncnn_2 1744_splitncnn_2 1745 +Convolution Conv_1043 1 1 1745 1747 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_247 1 2 1747 1747_splitncnn_0 1747_splitncnn_1 +Concat Concat_1045 4 1 1739_splitncnn_2 1741_splitncnn_1 1744_splitncnn_1 1747_splitncnn_1 1748 +Convolution Conv_1046 1 1 1748 1750 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1048 5 1 1739_splitncnn_1 1741_splitncnn_0 1744_splitncnn_0 1747_splitncnn_0 1750 1751 +Convolution Conv_1049 1 1 1751 1752 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1052 2 1 1752 1739_splitncnn_0 1755 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_248 1 6 1755 1755_splitncnn_0 1755_splitncnn_1 1755_splitncnn_2 1755_splitncnn_3 1755_splitncnn_4 1755_splitncnn_5 +Convolution Conv_1053 1 1 1755_splitncnn_5 1757 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_249 1 4 1757 1757_splitncnn_0 1757_splitncnn_1 1757_splitncnn_2 1757_splitncnn_3 +Concat Concat_1055 2 1 1755_splitncnn_4 1757_splitncnn_3 1758 +Convolution Conv_1056 1 1 1758 1760 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_250 1 3 1760 1760_splitncnn_0 1760_splitncnn_1 1760_splitncnn_2 +Concat Concat_1058 3 1 1755_splitncnn_3 1757_splitncnn_2 1760_splitncnn_2 1761 +Convolution Conv_1059 1 1 1761 1763 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_251 1 2 1763 1763_splitncnn_0 1763_splitncnn_1 +Concat Concat_1061 4 1 1755_splitncnn_2 1757_splitncnn_1 1760_splitncnn_1 1763_splitncnn_1 1764 +Convolution Conv_1062 1 1 1764 1766 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1064 5 1 1755_splitncnn_1 1757_splitncnn_0 1760_splitncnn_0 1763_splitncnn_0 1766 1767 +Convolution Conv_1065 1 1 1767 1768 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1068 2 1 1768 1755_splitncnn_0 1771 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_1071 2 1 1771 1723_splitncnn_0 1774 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_252 1 7 1774 1774_splitncnn_0 1774_splitncnn_1 1774_splitncnn_2 1774_splitncnn_3 1774_splitncnn_4 1774_splitncnn_5 1774_splitncnn_6 +Convolution Conv_1072 1 1 1774_splitncnn_6 1776 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_253 1 4 1776 1776_splitncnn_0 1776_splitncnn_1 1776_splitncnn_2 1776_splitncnn_3 +Concat Concat_1074 2 1 1774_splitncnn_5 1776_splitncnn_3 1777 +Convolution Conv_1075 1 1 1777 1779 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_254 1 3 1779 1779_splitncnn_0 1779_splitncnn_1 1779_splitncnn_2 +Concat Concat_1077 3 1 1774_splitncnn_4 1776_splitncnn_2 1779_splitncnn_2 1780 +Convolution Conv_1078 1 1 1780 1782 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_255 1 2 1782 1782_splitncnn_0 1782_splitncnn_1 +Concat Concat_1080 4 1 1774_splitncnn_3 1776_splitncnn_1 1779_splitncnn_1 1782_splitncnn_1 1783 +Convolution Conv_1081 1 1 1783 1785 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1083 5 1 1774_splitncnn_2 1776_splitncnn_0 1779_splitncnn_0 1782_splitncnn_0 1785 1786 +Convolution Conv_1084 1 1 1786 1787 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1087 2 1 1787 1774_splitncnn_1 1790 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_256 1 6 1790 1790_splitncnn_0 1790_splitncnn_1 1790_splitncnn_2 1790_splitncnn_3 1790_splitncnn_4 1790_splitncnn_5 +Convolution Conv_1088 1 1 1790_splitncnn_5 1792 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_257 1 4 1792 1792_splitncnn_0 1792_splitncnn_1 1792_splitncnn_2 1792_splitncnn_3 +Concat Concat_1090 2 1 1790_splitncnn_4 1792_splitncnn_3 1793 +Convolution Conv_1091 1 1 1793 1795 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_258 1 3 1795 1795_splitncnn_0 1795_splitncnn_1 1795_splitncnn_2 +Concat Concat_1093 3 1 1790_splitncnn_3 1792_splitncnn_2 1795_splitncnn_2 1796 +Convolution Conv_1094 1 1 1796 1798 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_259 1 2 1798 1798_splitncnn_0 1798_splitncnn_1 +Concat Concat_1096 4 1 1790_splitncnn_2 1792_splitncnn_1 1795_splitncnn_1 1798_splitncnn_1 1799 +Convolution Conv_1097 1 1 1799 1801 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1099 5 1 1790_splitncnn_1 1792_splitncnn_0 1795_splitncnn_0 1798_splitncnn_0 1801 1802 +Convolution Conv_1100 1 1 1802 1803 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1103 2 1 1803 1790_splitncnn_0 1806 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_260 1 6 1806 1806_splitncnn_0 1806_splitncnn_1 1806_splitncnn_2 1806_splitncnn_3 1806_splitncnn_4 1806_splitncnn_5 +Convolution Conv_1104 1 1 1806_splitncnn_5 1808 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_261 1 4 1808 1808_splitncnn_0 1808_splitncnn_1 1808_splitncnn_2 1808_splitncnn_3 +Concat Concat_1106 2 1 1806_splitncnn_4 1808_splitncnn_3 1809 +Convolution Conv_1107 1 1 1809 1811 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_262 1 3 1811 1811_splitncnn_0 1811_splitncnn_1 1811_splitncnn_2 +Concat Concat_1109 3 1 1806_splitncnn_3 1808_splitncnn_2 1811_splitncnn_2 1812 +Convolution Conv_1110 1 1 1812 1814 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_263 1 2 1814 1814_splitncnn_0 1814_splitncnn_1 +Concat Concat_1112 4 1 1806_splitncnn_2 1808_splitncnn_1 1811_splitncnn_1 1814_splitncnn_1 1815 +Convolution Conv_1113 1 1 1815 1817 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1115 5 1 1806_splitncnn_1 1808_splitncnn_0 1811_splitncnn_0 1814_splitncnn_0 1817 1818 +Convolution Conv_1116 1 1 1818 1819 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1119 2 1 1819 1806_splitncnn_0 1822 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_1122 2 1 1822 1774_splitncnn_0 1825 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_264 1 7 1825 1825_splitncnn_0 1825_splitncnn_1 1825_splitncnn_2 1825_splitncnn_3 1825_splitncnn_4 1825_splitncnn_5 1825_splitncnn_6 +Convolution Conv_1123 1 1 1825_splitncnn_6 1827 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_265 1 4 1827 1827_splitncnn_0 1827_splitncnn_1 1827_splitncnn_2 1827_splitncnn_3 +Concat Concat_1125 2 1 1825_splitncnn_5 1827_splitncnn_3 1828 +Convolution Conv_1126 1 1 1828 1830 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_266 1 3 1830 1830_splitncnn_0 1830_splitncnn_1 1830_splitncnn_2 +Concat Concat_1128 3 1 1825_splitncnn_4 1827_splitncnn_2 1830_splitncnn_2 1831 +Convolution Conv_1129 1 1 1831 1833 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_267 1 2 1833 1833_splitncnn_0 1833_splitncnn_1 +Concat Concat_1131 4 1 1825_splitncnn_3 1827_splitncnn_1 1830_splitncnn_1 1833_splitncnn_1 1834 +Convolution Conv_1132 1 1 1834 1836 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1134 5 1 1825_splitncnn_2 1827_splitncnn_0 1830_splitncnn_0 1833_splitncnn_0 1836 1837 +Convolution Conv_1135 1 1 1837 1838 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1138 2 1 1838 1825_splitncnn_1 1841 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_268 1 6 1841 1841_splitncnn_0 1841_splitncnn_1 1841_splitncnn_2 1841_splitncnn_3 1841_splitncnn_4 1841_splitncnn_5 +Convolution Conv_1139 1 1 1841_splitncnn_5 1843 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_269 1 4 1843 1843_splitncnn_0 1843_splitncnn_1 1843_splitncnn_2 1843_splitncnn_3 +Concat Concat_1141 2 1 1841_splitncnn_4 1843_splitncnn_3 1844 +Convolution Conv_1142 1 1 1844 1846 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_270 1 3 1846 1846_splitncnn_0 1846_splitncnn_1 1846_splitncnn_2 +Concat Concat_1144 3 1 1841_splitncnn_3 1843_splitncnn_2 1846_splitncnn_2 1847 +Convolution Conv_1145 1 1 1847 1849 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_271 1 2 1849 1849_splitncnn_0 1849_splitncnn_1 +Concat Concat_1147 4 1 1841_splitncnn_2 1843_splitncnn_1 1846_splitncnn_1 1849_splitncnn_1 1850 +Convolution Conv_1148 1 1 1850 1852 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1150 5 1 1841_splitncnn_1 1843_splitncnn_0 1846_splitncnn_0 1849_splitncnn_0 1852 1853 +Convolution Conv_1151 1 1 1853 1854 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1154 2 1 1854 1841_splitncnn_0 1857 0=1 -23301=2,2.000000e-01,1.000000e+00 +Split splitncnn_272 1 6 1857 1857_splitncnn_0 1857_splitncnn_1 1857_splitncnn_2 1857_splitncnn_3 1857_splitncnn_4 1857_splitncnn_5 +Convolution Conv_1155 1 1 1857_splitncnn_5 1859 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01 +Split splitncnn_273 1 4 1859 1859_splitncnn_0 1859_splitncnn_1 1859_splitncnn_2 1859_splitncnn_3 +Concat Concat_1157 2 1 1857_splitncnn_4 1859_splitncnn_3 1860 +Convolution Conv_1158 1 1 1860 1862 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01 +Split splitncnn_274 1 3 1862 1862_splitncnn_0 1862_splitncnn_1 1862_splitncnn_2 +Concat Concat_1160 3 1 1857_splitncnn_3 1859_splitncnn_2 1862_splitncnn_2 1863 +Convolution Conv_1161 1 1 1863 1865 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Split splitncnn_275 1 2 1865 1865_splitncnn_0 1865_splitncnn_1 +Concat Concat_1163 4 1 1857_splitncnn_2 1859_splitncnn_1 1862_splitncnn_1 1865_splitncnn_1 1866 +Convolution Conv_1164 1 1 1866 1868 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01 +Concat Concat_1166 5 1 1857_splitncnn_1 1859_splitncnn_0 1862_splitncnn_0 1865_splitncnn_0 1868 1869 +Convolution Conv_1167 1 1 1869 1870 0=64 1=3 4=1 5=1 6=110592 +Eltwise Add_1170 2 1 1870 1857_splitncnn_0 1873 0=1 -23301=2,2.000000e-01,1.000000e+00 +Eltwise Add_1173 2 1 1873 1825_splitncnn_0 1876 0=1 -23301=2,2.000000e-01,1.000000e+00 +Convolution Conv_1174 1 1 1876 1877 0=64 1=3 4=1 5=1 6=36864 +BinaryOp Add_1175 2 1 703_splitncnn_0 1877 1878 +Interp Resize_1177 1 1 1878 1883 0=1 1=2.000000e+00 2=2.000000e+00 +Convolution Conv_1178 1 1 1883 1885 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Interp Resize_1181 1 1 1885 1890 0=1 1=2.000000e+00 2=2.000000e+00 +Convolution Conv_1182 1 1 1890 1892 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Convolution Conv_1184 1 1 1892 1894 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01 +Convolution Conv_1186 1 1 1894 output 0=3 1=3 4=1 5=1 6=1728 diff --git a/realesrgan-bin/onepiece_demo.mp4 b/realesrgan-bin/onepiece_demo.mp4 new file mode 100644 index 0000000..29b4e52 Binary files /dev/null and b/realesrgan-bin/onepiece_demo.mp4 differ diff --git a/realesrgan-bin/realesrgan-ncnn-vulkan b/realesrgan-bin/realesrgan-ncnn-vulkan new file mode 100755 index 0000000..d071820 Binary files /dev/null and b/realesrgan-bin/realesrgan-ncnn-vulkan differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..32ef7e9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +# AI Video Upscaler — Python Dependencies +# Install: pip install -r requirements.txt + +fastapi>=0.115.0 +uvicorn>=0.30.0 +python-multipart>=0.0.9 +websockets>=13.0 +pydantic>=2.0 +torch>=2.0 diff --git a/restart.py b/restart.py new file mode 100755 index 0000000..803655d --- /dev/null +++ b/restart.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +""" +restart.py — Restart the AI Video Upscaler web application. + +Usage: + python restart.py # Restart on default port 8000 + python restart.py --port 9000 # Restart on a custom port +""" + +import argparse +import os +import sys +import time + +# Import siblings +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, BASE_DIR) + +from stop import stop +from start import start + + +def restart(host: str, port: int, open_browser: bool = True) -> None: + stop() + # Brief pause to let the port fully release + time.sleep(1) + start(host, port, open_browser=open_browser) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Restart the AI Video Upscaler") + parser.add_argument("--host", default="0.0.0.0", + help="Bind address (default: 0.0.0.0 to bind all interfaces, use 127.0.0.1 for local loopback only)") + parser.add_argument("--port", type=int, default=8000, + help="Port to listen on (default: 8000)") + parser.add_argument("--no-browser", action="store_true", + help="Don't open the browser automatically") + args = parser.parse_args() + + restart(args.host, args.port, open_browser=not args.no_browser) diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..cb10d9f --- /dev/null +++ b/setup.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash +# ── setup.sh — AI Video Upscaler environment setup ────────────────────────── +# +# Usage: +# chmod +x setup.sh && ./setup.sh +# +# Automates first-time setup on a new system: +# • Verifies required system tools (python3, ffmpeg, ffprobe) +# • Warns if Vulkan is unavailable +# • Creates a Python virtual environment and installs dependencies +# • Makes the Real-ESRGAN binary executable +# • Creates working directories (uploads, outputs, temp) +# ───────────────────────────────────────────────────────────────────────────── + +set -euo pipefail + +# ── Colors & Helpers ───────────────────────────────────────────────────────── +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +BOLD='\033[1m' +RESET='\033[0m' + +info() { echo -e "${CYAN}ℹ $*${RESET}"; } +ok() { echo -e "${GREEN}✅ $*${RESET}"; } +warn() { echo -e "${YELLOW}⚠ $*${RESET}"; } +fail() { echo -e "${RED}❌ $*${RESET}"; exit 1; } +step() { echo -e "\n${BOLD}── $* ──${RESET}"; } + +# ── Banner ─────────────────────────────────────────────────────────────────── +echo "" +echo -e "${BOLD}🔧 AI Video Upscaler — Setup${RESET}" +echo "" + +# ── Script Directory ───────────────────────────────────────────────────────── +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# ── 1. Check: python3 ─────────────────────────────────────────────────────── +step "Checking dependencies" + +if ! command -v python3 &>/dev/null; then + fail "python3 is not installed.\n Install it with your package manager (e.g. apt install python3, dnf install python3)." +fi +ok "python3 found — $(python3 --version)" + +# ── 2. Check: ffmpeg ──────────────────────────────────────────────────────── +if ! command -v ffmpeg &>/dev/null; then + fail "ffmpeg is not installed.\n Install it with your package manager:\n • Debian/Ubuntu : sudo apt install ffmpeg\n • Fedora/RHEL : sudo dnf install ffmpeg\n • Arch : sudo pacman -S ffmpeg" +fi +ok "ffmpeg found — $(ffmpeg -version | head -1)" + +# ── 3. Check: ffprobe ─────────────────────────────────────────────────────── +if ! command -v ffprobe &>/dev/null; then + fail "ffprobe is not installed (usually bundled with ffmpeg).\n Reinstall ffmpeg to get it." +fi +ok "ffprobe found" + +# ── 4. Check: vulkaninfo (optional) ───────────────────────────────────────── +if ! command -v vulkaninfo &>/dev/null; then + warn "vulkaninfo not found — Vulkan GPU acceleration is recommended but not required." + warn "Install vulkan-tools for GPU-accelerated upscaling." +else + ok "vulkaninfo found — Vulkan support detected" +fi + +# ── 5. Create Python venv ─────────────────────────────────────────────────── +step "Setting up Python virtual environment" + +if [ -d "$SCRIPT_DIR/venv" ]; then + info "venv already exists at $SCRIPT_DIR/venv — skipping creation." +else + info "Creating venv at $SCRIPT_DIR/venv …" + python3 -m venv "$SCRIPT_DIR/venv" + ok "Virtual environment created" +fi + +# ── 6. Install pip dependencies ───────────────────────────────────────────── +step "Installing Python dependencies" + +info "Running pip install -r requirements.txt …" +"$SCRIPT_DIR/venv/bin/pip" install --upgrade pip --quiet +"$SCRIPT_DIR/venv/bin/pip" install -r "$SCRIPT_DIR/requirements.txt" +ok "All Python dependencies installed" + +# ── 7. Make Real-ESRGAN binary executable ──────────────────────────────────── +step "Configuring Real-ESRGAN binary" + +if [ -f "$SCRIPT_DIR/realesrgan-bin/realesrgan-ncnn-vulkan" ]; then + chmod +x "$SCRIPT_DIR/realesrgan-bin/realesrgan-ncnn-vulkan" + ok "realesrgan-ncnn-vulkan marked as executable" +else + warn "realesrgan-ncnn-vulkan binary not found at $SCRIPT_DIR/realesrgan-bin/" + warn "You may need to download it manually." +fi + +# ── 8. Create working directories ─────────────────────────────────────────── +step "Creating working directories" + +for dir in uploads outputs temp; do + mkdir -p "$SCRIPT_DIR/$dir" +done +ok "Directories ready: uploads/ outputs/ temp/" + +# ── Done ───────────────────────────────────────────────────────────────────── +echo "" +echo -e "${GREEN}${BOLD}────────────────────────────────────────────${RESET}" +echo -e "${GREEN}${BOLD} ✅ Setup complete!${RESET}" +echo -e "${GREEN}${BOLD}────────────────────────────────────────────${RESET}" +echo "" +echo -e " Launch the server with:" +echo -e " ${CYAN}python start.py${RESET}" +echo "" diff --git a/start.py b/start.py new file mode 100755 index 0000000..cc9620c --- /dev/null +++ b/start.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 +""" +start.py — Start the AI Video Upscaler web application. + +Usage: + python start.py # Start on default port 8000 (binds to 0.0.0.0 for LAN access) + python start.py --port 9000 # Start on a custom port + python start.py --host 127.0.0.1 # Bind to loopback only (no LAN access) +""" + +import argparse +import os +import signal +import socket +import subprocess +import sys +import time +import webbrowser + +# ── Paths ──────────────────────────────────────────────────────────────────── +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +PID_FILE = os.path.join(BASE_DIR, ".uvicorn.pid") +LOG_FILE = os.path.join(BASE_DIR, "server.log") +# Detect the right Python interpreter: +# 1. If running inside an activated venv, use that interpreter +# 2. Otherwise look for venv/ then .venv/ in the project +if sys.prefix != sys.base_prefix: + # Already inside an activated venv — use it + VENV_PYTHON = sys.executable +else: + VENV_PYTHON = os.path.join(BASE_DIR, "venv", "bin", "python") + if not os.path.isfile(VENV_PYTHON): + VENV_PYTHON = os.path.join(BASE_DIR, ".venv", "bin", "python") + if not os.path.isfile(VENV_PYTHON): + VENV_PYTHON = sys.executable # last resort: system python + + +def _is_running(pid: int) -> bool: + """Check whether a process with the given PID is still alive and is our server.""" + try: + os.kill(pid, 0) + except OSError: + return False + + # Check /proc/{pid}/cmdline to verify it's our server process + try: + cmdline_path = f"/proc/{pid}/cmdline" + if os.path.exists(cmdline_path): + with open(cmdline_path, "r") as f: + cmdline = f.read() + # Check for indicators of our server + return "uvicorn" in cmdline or "app.main" in cmdline + except Exception: + pass + # If we can't read cmdline, default to True (safer fallback) + return True + + +def _read_pid() -> int | None: + """Read and validate the PID from the pidfile.""" + if not os.path.isfile(PID_FILE): + return None + try: + pid = int(open(PID_FILE).read().strip()) + return pid if _is_running(pid) else None + except (ValueError, OSError): + return None + + +def _get_local_ip() -> str: + """Get the primary local network IP address.""" + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + # Dummy connection to google DNS to get local route IP + s.connect(("8.8.8.8", 80)) + ip = s.getsockname()[0] + except Exception: + try: + ip = socket.gethostbyname(socket.gethostname()) + except Exception: + ip = "127.0.0.1" + finally: + s.close() + return ip + + +def start(host: str, port: int, open_browser: bool = True) -> None: + existing = _read_pid() + if existing: + print(f"⚠ Server is already running (PID {existing}).") + if host == "0.0.0.0": + local_ip = _get_local_ip() + print(f" → Local: http://localhost:{port}") + if local_ip and local_ip != "127.0.0.1": + print(f" → Network: http://{local_ip}:{port}") + else: + print(f" → http://{host}:{port}") + return + + print(f"🚀 Starting AI Video Upscaler …") + print(f" Host : {host}") + print(f" Port : {port}") + print(f" Log : {LOG_FILE}") + + log_fh = open(LOG_FILE, "a") + + proc = subprocess.Popen( + [ + VENV_PYTHON, "-m", "uvicorn", + "app.main:app", + "--host", host, + "--port", str(port), + ], + cwd=BASE_DIR, + stdout=log_fh, + stderr=log_fh, + start_new_session=True, # detach from terminal + ) + + # Write PID + with open(PID_FILE, "w") as f: + f.write(str(proc.pid)) + + # Wait briefly to make sure it didn't crash immediately + time.sleep(1.5) + if proc.poll() is not None: + print("❌ Server failed to start. Check server.log for details.") + os.remove(PID_FILE) + sys.exit(1) + + url = f"http://{'localhost' if host == '0.0.0.0' else host}:{port}" + print(f"✅ Server started (PID {proc.pid})") + if host == "0.0.0.0": + local_ip = _get_local_ip() + print(f" → Local: http://localhost:{port}") + if local_ip and local_ip != "127.0.0.1": + print(f" → Network: http://{local_ip}:{port}") + else: + print(f" → {url}") + + if open_browser: + webbrowser.open(url) + + +# ── CLI ────────────────────────────────────────────────────────────────────── +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Start the AI Video Upscaler") + parser.add_argument("--host", default="0.0.0.0", + help="Bind address (default: 0.0.0.0 to bind all interfaces, use 127.0.0.1 for local loopback only)") + parser.add_argument("--port", type=int, default=8000, + help="Port to listen on (default: 8000)") + parser.add_argument("--no-browser", action="store_true", + help="Don't open the browser automatically") + args = parser.parse_args() + + start(args.host, args.port, open_browser=not args.no_browser) diff --git a/static/app.js b/static/app.js new file mode 100644 index 0000000..4a1487f --- /dev/null +++ b/static/app.js @@ -0,0 +1,1483 @@ +// App State +let uploadFileId = null; +let uploadMetadata = null; +let currentJobId = null; +let socket = null; +let sliderInitialized = false; + +// Error formatting helper +function formatFetchError(err, defaultMsg) { + if (!err) return defaultMsg; + if (typeof err === "string") return err; + if (err.detail) { + if (typeof err.detail === "string") { + return err.detail; + } + if (Array.isArray(err.detail)) { + return err.detail.map(d => { + const locStr = (d.loc && Array.isArray(d.loc)) ? d.loc.join(".") : ""; + return locStr ? `${locStr}: ${d.msg}` : (d.msg || JSON.stringify(d)); + }).join("\n"); + } + if (typeof err.detail === "object") { + return err.detail.message || err.detail.error || JSON.stringify(err.detail); + } + } + if (err.message) return err.message; + return JSON.stringify(err) || defaultMsg; +} + +// DOM Elements +const stepUpload = document.getElementById("step-upload"); +const stepConfig = document.getElementById("step-config"); +const stepProgress = document.getElementById("step-progress"); +const stepFinished = document.getElementById("step-finished"); + +const dropZone = document.getElementById("drop-zone"); +const fileInput = document.getElementById("file-input"); + +// Meta fields +const metaName = document.getElementById("meta-name"); +const metaSize = document.getElementById("meta-size"); +const metaRes = document.getElementById("meta-res"); +const metaDuration = document.getElementById("meta-duration"); +const metaFps = document.getElementById("meta-fps"); + +// Config inputs +const modelSelect = document.getElementById("model-select"); +const scaleRange = document.getElementById("scale-range"); +const scaleValue = document.getElementById("scale-value"); +const tileRange = document.getElementById("tile-range"); +const tileValue = document.getElementById("tile-value"); +const audioToggle = document.getElementById("audio-toggle"); + +// Timeline and Preview elements +const timelineSlider = document.getElementById("timeline-slider"); +const timelineTime = document.getElementById("timeline-time"); +const generatePreviewBtn = document.getElementById("generate-preview-btn"); +const generateVideoPreviewBtn = document.getElementById("generate-video-preview-btn"); +const previewPlaceholderBox = document.getElementById("preview-placeholder-box"); +const comparisonSliderContainer = document.getElementById("comparison-slider-container"); +const previewLoader = document.getElementById("preview-loader"); +const imgOriginal = document.getElementById("img-original"); +const imgUpscaled = document.getElementById("img-upscaled"); +const sliderSplit = document.getElementById("slider-split"); + +// Progress elements +const jobIdDisplay = document.getElementById("job-id-display"); +const statusBadge = document.getElementById("status-badge"); +const progressPercent = document.getElementById("progress-percent"); +const progressBarFill = document.getElementById("progress-bar-fill"); +const statStatus = document.getElementById("stat-status"); +const statFrames = document.getElementById("stat-frames"); +const statEta = document.getElementById("stat-eta"); +const logTerminal = document.getElementById("log-terminal"); +const cancelUpscaleBtn = document.getElementById("cancel-upscale-btn"); +const startUpscaleBtn = document.getElementById("start-upscale-btn"); + +// Finished elements +const downloadLink = document.getElementById("download-link"); +const finishedPlayComparisonBtn = document.getElementById("finished-play-comparison-btn"); + +// Synced Playback Modal Elements +const videoModal = document.getElementById("video-modal"); +const modalVideoOriginal = document.getElementById("modal-video-original"); +const modalVideoUpscaled = document.getElementById("modal-video-upscaled"); +const modalPlayBtn = document.getElementById("modal-play-btn"); +const modalTimeSlider = document.getElementById("modal-time-slider"); +const modalTimeCurrent = document.getElementById("modal-time-current"); +const modalTimeDuration = document.getElementById("modal-time-duration"); +const modalMuteBtn = document.getElementById("modal-mute-btn"); +const modalCloseBtn = document.getElementById("modal-close-btn"); + + +/* ---------------------------------------------------- + 1. Theme Selector + ---------------------------------------------------- */ +const themeSelect = document.getElementById("theme-select"); +function applyTheme(theme) { + document.body.className = ""; + if (theme && theme !== "cyberpunk") { + document.body.classList.add(`theme-${theme}`); + } else { + document.body.classList.add("theme-cyberpunk"); + } + localStorage.setItem("selected-theme", theme); + if (themeSelect) themeSelect.value = theme; +} + +if (themeSelect) { + themeSelect.addEventListener("change", (e) => { + applyTheme(e.target.value); + }); +} +applyTheme(localStorage.getItem("selected-theme") || "cyberpunk"); + + +/* ---------------------------------------------------- + 2. Dynamic Sliders & Parameter Listeners + ---------------------------------------------------- */ +scaleRange.addEventListener("input", (e) => { + scaleValue.textContent = `${e.target.value}x`; + // Lock model scaling if needed: Real-ESRGAN x4 models are scale 4. Real-ESRGAN-animevideov3 supports 2,3,4. + const model = modelSelect.value; + if (model.includes("x4plus") && e.target.value !== "4") { + scaleRange.value = 4; + scaleValue.textContent = "4x (Locked)"; + } +}); + +modelSelect.addEventListener("change", (e) => { + const val = e.target.value; + if (val.includes("x4plus")) { + scaleRange.value = 4; + scaleRange.disabled = true; + scaleValue.textContent = "4x (Fixed)"; + } else { + scaleRange.disabled = false; + scaleValue.textContent = `${scaleRange.value}x`; + } +}); + +tileRange.addEventListener("input", (e) => { + tileValue.textContent = e.target.value === "0" ? "Auto" : e.target.value; +}); + +const crfRange = document.getElementById("crf-range"); +const crfValue = document.getElementById("crf-value"); +if (crfRange && crfValue) { + crfRange.addEventListener("input", (e) => { + let label = e.target.value; + if (e.target.value === "0") label += " (Lossless)"; + else if (e.target.value === "18") label += " (Pristine)"; + else if (e.target.value > "28") label += " (Compress)"; + crfValue.textContent = label; + }); +} + + +/* ---------------------------------------------------- + 3. Custom Model Upload Action + ---------------------------------------------------- */ +const customModelInput = document.getElementById("custom-model-input"); +const modelUploadFilename = document.getElementById("model-upload-filename"); +const uploadModelBtnWrapper = document.getElementById("upload-model-btn-wrapper"); +const uploadModelBtn = document.getElementById("upload-model-btn"); + +if (customModelInput) { + customModelInput.addEventListener("change", (e) => { + const files = e.target.files; + if (files.length > 0) { + const names = Array.from(files).map(f => f.name).join(", "); + modelUploadFilename.textContent = names; + uploadModelBtnWrapper.style.display = "block"; + } else { + modelUploadFilename.textContent = "No files selected"; + uploadModelBtnWrapper.style.display = "none"; + } + }); +} + +if (uploadModelBtn) { + uploadModelBtn.addEventListener("click", async () => { + const files = customModelInput.files; + if (files.length === 0) return; + + uploadModelBtn.disabled = true; + uploadModelBtn.innerHTML = `
Uploading...`; + + const formData = new FormData(); + for (let i = 0; i < files.length; i++) { + const ext = files[i].name.split('.').pop().toLowerCase(); + if (ext === 'param') { + formData.append("param_file", files[i]); + } else if (ext === 'bin') { + formData.append("bin_file", files[i]); + } else { + formData.append("files", files[i]); + } + } + + try { + const res = await fetch("/api/models/upload", { + method: "POST", + body: formData + }); + if (!res.ok) { + const err = await res.json(); + throw new Error(formatFetchError(err, "Model upload failed.")); + } + alert("Custom model uploaded successfully!"); + modelUploadFilename.textContent = "Uploaded successfully!"; + uploadModelBtnWrapper.style.display = "none"; + await loadModels(); + } catch (err) { + alert(err.message); + } finally { + uploadModelBtn.disabled = false; + uploadModelBtn.innerHTML = ` Upload Model Files`; + } + }); +} + + +/* ---------------------------------------------------- + 4. Video File Upload Routing + ---------------------------------------------------- */ +['dragenter', 'dragover'].forEach(eventName => { + dropZone.addEventListener(eventName, (e) => { + e.preventDefault(); + dropZone.classList.add('drag-over'); + }, false); +}); + +['dragleave', 'drop'].forEach(eventName => { + dropZone.addEventListener(eventName, (e) => { + e.preventDefault(); + dropZone.classList.remove('drag-over'); + }, false); +}); + +dropZone.addEventListener('drop', (e) => { + const dt = e.dataTransfer; + const files = dt.files; + if (files.length) handleVideoUpload(files[0]); +}); + +fileInput.addEventListener('change', (e) => { + if (e.target.files.length) handleVideoUpload(e.target.files[0]); +}); + +function formatBytes(bytes, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} + +function handleVideoUpload(file) { + dropZone.innerHTML = ` +
+

Uploading Video File...

+

Preparing upload...

+
+
+
+ `; + + const formData = new FormData(); + formData.append("file", file); + + const xhr = new XMLHttpRequest(); + xhr.open("POST", "/api/upload", true); + + xhr.upload.addEventListener("progress", (e) => { + if (e.lengthComputable) { + const percentComplete = (e.loaded / e.total) * 100; + const progressText = document.getElementById("upload-progress-text"); + const progressBar = document.getElementById("upload-bar"); + if (progressText) progressText.textContent = `Uploaded ${formatBytes(e.loaded)} / ${formatBytes(e.total)} (${Math.round(percentComplete)}%)`; + if (progressBar) progressBar.style.width = `${percentComplete}%`; + } + }); + + xhr.onload = function() { + if (xhr.status === 200) { + const res = JSON.parse(xhr.responseText); + uploadFileId = res.file_id; + uploadMetadata = res.metadata; + + // Populate Config Step Info + metaName.textContent = res.filename; + metaSize.textContent = formatBytes(file.size); + + // Populate Accordions Stream details + const streams = res.metadata.streams || []; + const videoStream = streams.find(s => s.codec_type === "video") || {}; + const audioStream = streams.find(s => s.codec_type === "audio") || {}; + + // Video stream metadata + document.getElementById("meta-res-codec").textContent = (videoStream.codec_name || "unknown").toUpperCase(); + document.getElementById("meta-res").textContent = `${res.metadata.width} x ${res.metadata.height}`; + document.getElementById("meta-fps").textContent = `${res.metadata.fps} FPS`; + document.getElementById("meta-duration").textContent = `${res.metadata.duration}s`; + document.getElementById("meta-total-frames").textContent = res.metadata.total_frames || "-"; + document.getElementById("meta-aspect-ratio").textContent = videoStream.display_aspect_ratio || "N/A"; + + // Audio stream metadata + if (audioStream.codec_name) { + document.getElementById("meta-audio-codec").textContent = (audioStream.codec_name || "unknown").toUpperCase(); + document.getElementById("meta-audio-channels").textContent = audioStream.channels || "N/A"; + document.getElementById("meta-audio-samplerate").textContent = audioStream.sample_rate ? `${audioStream.sample_rate} Hz` : "N/A"; + document.getElementById("meta-audio-bitrate").textContent = audioStream.bit_rate ? formatBytes(parseInt(audioStream.bit_rate)) + "/s" : "N/A"; + } else { + document.getElementById("meta-audio-codec").textContent = "No Audio Stream"; + document.getElementById("meta-audio-channels").textContent = "-"; + document.getElementById("meta-audio-samplerate").textContent = "-"; + document.getElementById("meta-audio-bitrate").textContent = "-"; + } + + // Configure timeline slider constraints + timelineSlider.min = 0.1; + timelineSlider.max = res.metadata.duration - 0.5; + timelineSlider.value = (res.metadata.duration * 0.15).toFixed(2); + timelineTime.textContent = `${timelineSlider.value}s`; + + // Configure Trimming panel range values + const trimStartRange = document.getElementById("trim-start-range"); + const trimEndRange = document.getElementById("trim-end-range"); + const trimStartValue = document.getElementById("trim-start-value"); + const trimEndValue = document.getElementById("trim-end-value"); + + trimStartRange.min = 0; + trimStartRange.max = res.metadata.duration; + trimStartRange.value = 0; + trimStartValue.textContent = "0.00s"; + + trimEndRange.min = 0; + trimEndRange.max = res.metadata.duration; + trimEndRange.value = res.metadata.duration; + trimEndValue.textContent = `${res.metadata.duration.toFixed(2)}s`; + + // Show config view + stepUpload.classList.remove("active"); + stepConfig.classList.add("active"); + } else { + alert("Upload failed: " + (JSON.parse(xhr.responseText).detail || xhr.statusText)); + window.location.reload(); + } + }; + + xhr.onerror = function() { + alert("Upload error occurred."); + window.location.reload(); + }; + + xhr.send(formData); +} + +// Timeline slider change +timelineSlider.addEventListener("input", (e) => { + timelineTime.textContent = `${parseFloat(e.target.value).toFixed(2)}s`; +}); + +// Trimming sliders inputs listeners +const trimStartRange = document.getElementById("trim-start-range"); +const trimEndRange = document.getElementById("trim-end-range"); +const trimStartValue = document.getElementById("trim-start-value"); +const trimEndValue = document.getElementById("trim-end-value"); + +trimStartRange.addEventListener("input", (e) => { + let val = parseFloat(e.target.value); + const endVal = parseFloat(trimEndRange.value); + if (val >= endVal) { + val = endVal - 0.05; + trimStartRange.value = val; + } + trimStartValue.textContent = `${val.toFixed(2)}s`; +}); + +trimEndRange.addEventListener("input", (e) => { + let val = parseFloat(e.target.value); + const startVal = parseFloat(trimStartRange.value); + if (val <= startVal) { + val = startVal + 0.05; + trimEndRange.value = val; + } + trimEndValue.textContent = `${val.toFixed(2)}s`; +}); + + +/* ---------------------------------------------------- + 5. Single Frame Preview Comparisons & Synced Zoom/Pan + ---------------------------------------------------- */ +const zoomSlider = document.getElementById("zoom-slider"); +const zoomVal = document.getElementById("zoom-val"); +const panXSlider = document.getElementById("pan-x-slider"); +const panXVal = document.getElementById("pan-x-val"); +const panYSlider = document.getElementById("pan-y-slider"); +const panYVal = document.getElementById("pan-y-val"); +const resetZoomPanBtn = document.getElementById("reset-zoom-pan-btn"); + +let previewZoom = 1.0; +let previewPanX = 0; +let previewPanY = 0; + +function updatePreviewTransform() { + const transformStr = `translate(${previewPanX}px, ${previewPanY}px) scale(${previewZoom})`; + + imgOriginal.style.transform = transformStr; + imgOriginal.style.transformOrigin = "center center"; + imgOriginal.style.transition = "transform 0.1s ease-out"; + + imgUpscaled.style.transform = transformStr; + imgUpscaled.style.transformOrigin = "center center"; + imgUpscaled.style.transition = "transform 0.1s ease-out"; + + const vidOriginal = document.getElementById("video-preview-original"); + const vidUpscaled = document.getElementById("video-preview-upscaled"); + if (vidOriginal) { + vidOriginal.style.transform = transformStr; + vidOriginal.style.transformOrigin = "center center"; + vidOriginal.style.transition = "transform 0.1s ease-out"; + } + if (vidUpscaled) { + vidUpscaled.style.transform = transformStr; + vidUpscaled.style.transformOrigin = "center center"; + vidUpscaled.style.transition = "transform 0.1s ease-out"; + } + + zoomSlider.value = previewZoom; + zoomVal.textContent = `${previewZoom.toFixed(1)}x`; + + panXSlider.value = previewPanX; + panXVal.textContent = `${previewPanX}px`; + + panYSlider.value = previewPanY; + panYVal.textContent = `${previewPanY}px`; +} + +zoomSlider.addEventListener("input", (e) => { + previewZoom = parseFloat(e.target.value); + updatePreviewTransform(); +}); + +panXSlider.addEventListener("input", (e) => { + previewPanX = parseInt(e.target.value); + updatePreviewTransform(); +}); + +panYSlider.addEventListener("input", (e) => { + previewPanY = parseInt(e.target.value); + updatePreviewTransform(); +}); + +resetZoomPanBtn.addEventListener("click", () => { + previewZoom = 1.0; + previewPanX = 0; + previewPanY = 0; + updatePreviewTransform(); +}); + +// Dragging to pan comparison image +let isDraggingPreview = false; +let startDragX = 0; +let startDragY = 0; + +comparisonSliderContainer.addEventListener("mousedown", (e) => { + if (e.target.id === "slider-split" || e.target.classList.contains("slider-handle")) { + return; + } + isDraggingPreview = true; + startDragX = e.clientX - previewPanX; + startDragY = e.clientY - previewPanY; + comparisonSliderContainer.style.cursor = "grabbing"; +}); + +window.addEventListener("mouseup", () => { + if (isDraggingPreview) { + isDraggingPreview = false; + comparisonSliderContainer.style.cursor = "default"; + } +}); + +window.addEventListener("mousemove", (e) => { + if (!isDraggingPreview) return; + previewPanX = e.clientX - startDragX; + previewPanY = e.clientY - startDragY; + + if (previewPanX < -400) previewPanX = -400; + if (previewPanX > 400) previewPanX = 400; + if (previewPanY < -400) previewPanY = -400; + if (previewPanY > 400) previewPanY = 400; + + updatePreviewTransform(); +}); + +// Generate single frame preview trigger +generatePreviewBtn.addEventListener("click", async () => { + if (!uploadFileId) return; + + const loaderTitle = document.getElementById("preview-loader-title"); + const loaderContainer = document.getElementById("preview-loader-progress-container"); + const loaderText = document.getElementById("preview-loader-text"); + + previewLoader.style.display = "flex"; + previewPlaceholderBox.style.display = "none"; + comparisonSliderContainer.style.display = "none"; + document.getElementById("zoom-pan-controls").style.display = "none"; + document.getElementById("video-preview-controls").style.display = "none"; + + if (loaderTitle) loaderTitle.textContent = "Orchestrating Vulkan GPU..."; + if (loaderContainer) loaderContainer.style.display = "none"; + if (loaderText) loaderText.textContent = "Extracting and upscaling frame. Please wait..."; + + const gpuSelect = document.getElementById("gpu-select"); + + try { + const res = await fetch("/api/preview/generate", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + file_id: uploadFileId, + timestamp_sec: parseFloat(timelineSlider.value), + model: modelSelect.value, + scale: parseInt(scaleRange.value), + tile_size: parseInt(tileRange.value), + gpu_ids: gpuSelect.value === 'auto' ? null : gpuSelect.value + }) + }); + + if (!res.ok) { + const err = await res.json(); + throw new Error(formatFetchError(err, "Frame preview rendering failed.")); + } + + const data = await res.json(); + const previewId = data.preview_id; + + imgOriginal.src = `/api/preview/original/${previewId}?t=${Date.now()}`; + imgUpscaled.src = `/api/preview/upscaled/${previewId}?t=${Date.now()}`; + + await Promise.all([ + new Promise(resolve => imgOriginal.onload = resolve), + new Promise(resolve => imgUpscaled.onload = resolve) + ]); + + // Hide videos, show images + imgOriginal.style.display = "block"; + document.getElementById("img-upscaled-wrapper").style.display = "block"; + + document.getElementById("video-preview-original").style.display = "none"; + document.getElementById("video-preview-upscaled-wrapper").style.display = "none"; + + previewPlaceholderBox.style.display = "none"; + comparisonSliderContainer.style.display = "block"; + document.getElementById("zoom-pan-controls").style.display = "flex"; + + initComparisonSlider(); + + // Reset transforms + previewZoom = 1.0; + previewPanX = 0; + previewPanY = 0; + updatePreviewTransform(); + + } catch (err) { + alert(err.message); + } finally { + previewLoader.style.display = "none"; + } +}); + +generateVideoPreviewBtn.addEventListener("click", async () => { + if (!uploadFileId) return; + + const loaderTitle = document.getElementById("preview-loader-title"); + const loaderContainer = document.getElementById("preview-loader-progress-container"); + const loaderBar = document.getElementById("preview-loader-progress-bar"); + const loaderText = document.getElementById("preview-loader-text"); + + previewLoader.style.display = "flex"; + previewPlaceholderBox.style.display = "none"; + comparisonSliderContainer.style.display = "none"; + document.getElementById("zoom-pan-controls").style.display = "none"; + document.getElementById("video-preview-controls").style.display = "none"; + + if (loaderTitle) loaderTitle.textContent = "Generating Video Preview"; + if (loaderContainer) loaderContainer.style.display = "block"; + if (loaderBar) loaderBar.style.width = "0%"; + if (loaderText) loaderText.textContent = "Queuing preview job in pipeline..."; + + const gpuSelect = document.getElementById("gpu-select"); + const crfRange = document.getElementById("crf-range"); + const presetSelect = document.getElementById("preset-select"); + const transcodeSelect = document.getElementById("transcode-select"); + const filterDenoise = document.getElementById("filter-denoise"); + const filterSharpen = document.getElementById("filter-sharpen"); + const filterFps = document.getElementById("filter-fps"); + + const transcodeFormat = transcodeSelect.value; + + try { + const res = await fetch("/api/upscale/start", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + file_id: uploadFileId, + model: modelSelect.value, + scale: parseInt(scaleRange.value), + tile_size: parseInt(tileRange.value), + preserve_audio: audioToggle.checked, + start_sec: parseFloat(timelineSlider.value), + end_sec: parseFloat(timelineSlider.value) + 5.0, + gpu_ids: gpuSelect.value === 'auto' ? null : gpuSelect.value, + tta: false, + unsharp: false, + double_fps: false, + preserve_subtitles: false, + crf: parseInt(crfRange.value), + preset: presetSelect.value, + denoise: filterDenoise.checked, + sharpen: filterSharpen.checked, + interpolation: filterFps.checked, + webhook_url: null, + transcode_format: transcodeFormat, + is_preview: true + }) + }); + + if (!res.ok) { + const err = await res.json(); + throw new Error(formatFetchError(err, "Failed to start video preview.")); + } + + const data = await res.json(); + currentJobId = data.job_id; + + connectProgressWebSocket(currentJobId); + + } catch (err) { + alert(err.message); + previewLoader.style.display = "none"; + previewPlaceholderBox.style.display = "flex"; + } +}); + +function initComparisonSlider() { + const upscaledWrapper = document.getElementById("img-upscaled-wrapper"); + const videoUpscaledWrapper = document.getElementById("video-preview-upscaled-wrapper"); + + // Reset split positions to 50% + if (upscaledWrapper) upscaledWrapper.style.clipPath = `inset(0 0 0 50%)`; + if (videoUpscaledWrapper) videoUpscaledWrapper.style.clipPath = `inset(0 0 0 50%)`; + sliderSplit.style.left = `50%`; + + if (sliderInitialized) return; + sliderInitialized = true; + + let active = false; + + function setSliderPosition(x) { + const rect = comparisonSliderContainer.getBoundingClientRect(); + let posX = x - rect.left; + if (posX < 0) posX = 0; + if (posX > rect.width) posX = rect.width; + + const pct = (posX / rect.width) * 100; + if (upscaledWrapper) upscaledWrapper.style.clipPath = `inset(0 0 0 ${pct}%)`; + if (videoUpscaledWrapper) videoUpscaledWrapper.style.clipPath = `inset(0 0 0 ${pct}%)`; + sliderSplit.style.left = `${pct}%`; + } + + sliderSplit.addEventListener('mousedown', (e) => { e.stopPropagation(); active = true; }); + window.addEventListener('mouseup', () => { active = false; }); + window.addEventListener('mousemove', (e) => { + if (!active) return; + setSliderPosition(e.pageX); + }); + + sliderSplit.addEventListener('touchstart', (e) => { e.stopPropagation(); active = true; }); + window.addEventListener('touchend', () => { active = false; }); + window.addEventListener('touchmove', (e) => { + if (!active) return; + setSliderPosition(e.touches[0].pageX); + }); + + comparisonSliderContainer.addEventListener('dblclick', () => { + upscaledWrapper.style.clipPath = `inset(0 0 0 50%)`; + sliderSplit.style.left = `50%`; + }); +} + + +/* ---------------------------------------------------- + 6. Video Pipeline Jobs Orchestration + ---------------------------------------------------- */ +startUpscaleBtn.addEventListener("click", async () => { + if (!uploadFileId) return; + + startUpscaleBtn.disabled = true; + startUpscaleBtn.innerHTML = `
Starting Job...`; + + const gpuSelect = document.getElementById("gpu-select"); + const crfRange = document.getElementById("crf-range"); + const presetSelect = document.getElementById("preset-select"); + const transcodeSelect = document.getElementById("transcode-select"); + const filterDenoise = document.getElementById("filter-denoise"); + const filterSharpen = document.getElementById("filter-sharpen"); + const filterFps = document.getElementById("filter-fps"); + const webhookUrl = document.getElementById("webhook-url"); + + try { + const res = await fetch("/api/upscale/start", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + file_id: uploadFileId, + model: modelSelect.value, + scale: parseInt(scaleRange.value), + tile_size: parseInt(tileRange.value), + preserve_audio: audioToggle.checked, + + // Advanced fields + start_sec: parseFloat(trimStartRange.value), + end_sec: parseFloat(trimEndRange.value), + gpu_ids: gpuSelect.value === "auto" ? null : gpuSelect.value, + crf: parseInt(crfRange.value), + preset: presetSelect.value, + transcode_format: transcodeSelect.value, + denoise: filterDenoise.checked, + sharpen: filterSharpen.checked, + interpolation: filterFps.checked, + webhook_url: webhookUrl.value.trim() || null + }) + }); + + if (!res.ok) { + const err = await res.json(); + throw new Error(formatFetchError(err, "Orchestrator failed to launch job.")); + } + + const data = await res.json(); + currentJobId = data.job_id; + + stepConfig.classList.remove("active"); + stepProgress.classList.add("active"); + jobIdDisplay.textContent = currentJobId; + + connectProgressWebSocket(currentJobId); + + } catch (err) { + alert(err.message); + startUpscaleBtn.disabled = false; + startUpscaleBtn.innerHTML = ` Start Full Upscale`; + } +}); + +function connectProgressWebSocket(jobId) { + const loc = window.location; + const protocol = loc.protocol === "https:" ? "wss:" : "ws:"; + const wsUrl = `${protocol}//${loc.host}/ws/progress/${jobId}`; + + socket = new WebSocket(wsUrl); + logTerminal.innerHTML = `
Connected to backend job orchestrator...
`; + + socket.onmessage = function(event) { + const data = JSON.parse(event.data); + updateProgressUI(data); + }; + + socket.onclose = function() { + console.log("WebSocket progress connection closed"); + }; + + socket.onerror = function(err) { + console.error("WebSocket error:", err); + startFallbackPolling(jobId); + }; +} + +function appendLogLine(text, type = "info") { + const line = document.createElement("div"); + line.className = `log-line ${type}`; + line.textContent = `[${new Date().toLocaleTimeString()}] ${text}`; + logTerminal.appendChild(line); + logTerminal.scrollTop = logTerminal.scrollHeight; +} + +function updateProgressUI(data) { + if (data.is_preview) { + // Update inline loader inside the preview panel + const loaderTitle = document.getElementById("preview-loader-title"); + const loaderContainer = document.getElementById("preview-loader-progress-container"); + const loaderBar = document.getElementById("preview-loader-progress-bar"); + const loaderText = document.getElementById("preview-loader-text"); + + if (previewLoader.style.display !== "flex") { + previewLoader.style.display = "flex"; + previewPlaceholderBox.style.display = "none"; + comparisonSliderContainer.style.display = "none"; + document.getElementById("zoom-pan-controls").style.display = "none"; + document.getElementById("video-preview-controls").style.display = "none"; + } + + if (loaderTitle) loaderTitle.textContent = "Generating Video Preview"; + if (loaderContainer) loaderContainer.style.display = "block"; + if (loaderBar) loaderBar.style.width = `${Math.round(data.progress || 0)}%`; + + let statusText = `Status: ${data.status}`; + if (data.status === "upscaling" && data.total_frames > 0) { + statusText = `Upscaling frame ${data.current_frame} of ${data.total_frames} (ETA: ${data.eta})`; + } else if (data.status === "queued") { + statusText = "Queued in pipeline. Waiting for GPU lock..."; + } else if (data.status === "extracting") { + statusText = "Extracting video frames..."; + } else if (data.status === "assembling") { + statusText = "Assembling video preview and audio tracks..."; + } + if (loaderText) loaderText.textContent = statusText; + + if (data.status === "completed") { + if (socket) socket.close(); + + // Hide loader + previewLoader.style.display = "none"; + + // Show comparison elements + previewPlaceholderBox.style.display = "none"; + comparisonSliderContainer.style.display = "block"; + document.getElementById("zoom-pan-controls").style.display = "flex"; + document.getElementById("video-preview-controls").style.display = "flex"; + + // Toggle elements visibility: hide images, show videos + imgOriginal.style.display = "none"; + document.getElementById("img-upscaled-wrapper").style.display = "none"; + + const vidOriginal = document.getElementById("video-preview-original"); + const vidUpscaledWrapper = document.getElementById("video-preview-upscaled-wrapper"); + const vidUpscaled = document.getElementById("video-preview-upscaled"); + + vidOriginal.style.display = "block"; + vidUpscaledWrapper.style.display = "block"; + + vidOriginal.src = `/api/download/${data.original_preview_file}`; + vidUpscaled.src = `/api/download/${data.output_file}`; + + vidOriginal.load(); + vidUpscaled.load(); + + initComparisonSlider(); + initVideoPreviewControls(vidOriginal, vidUpscaled); + + // Reset zoom/pan + previewZoom = 1.0; + previewPanX = 0; + previewPanY = 0; + updatePreviewTransform(); + } else if (data.status === "failed") { + alert(`Preview generation failed: ${data.error}`); + previewLoader.style.display = "none"; + previewPlaceholderBox.style.display = "flex"; + } + + loadQueue(); + return; + } + + statusBadge.className = `status-badge ${data.status}`; + statusBadge.textContent = data.status; + + statStatus.textContent = data.status.toUpperCase(); + if (data.total_frames > 0) { + statFrames.textContent = `${data.current_frame} / ${data.total_frames}`; + } else { + statFrames.textContent = "-"; + } + statEta.textContent = data.eta || "Calculating..."; + + const progressVal = Math.round(data.progress || 0); + progressPercent.textContent = `${progressVal}%`; + progressBarFill.style.width = `${progressVal}%`; + + if (data.status === "queued") { + appendLogLine("Job added to FIFO queue. Waiting for GPU lock...", "info"); + } else if (data.status === "analyzing") { + appendLogLine("GPU locked. Analyzing video parameters & framerates...", "info"); + } else if (data.status === "extracting") { + appendLogLine("FFmpeg: Splitting video stream to high-fidelity JPG frames...", "info"); + } else if (data.status === "upscaling") { + appendLogLine(`Vulkan GPU: Processing frame ${data.current_frame} of ${data.total_frames} (ETA: ${data.eta})...`, "info"); + } else if (data.status === "assembling") { + appendLogLine("FFmpeg: Reassembling enhanced frames & merging audio tracks...", "info"); + } else if (data.status === "completed") { + appendLogLine("Success! Upscaling process finished cleanly. Temp files deleted.", "success"); + + setTimeout(() => { + if (socket) socket.close(); + stepProgress.classList.remove("active"); + stepFinished.classList.add("active"); + downloadLink.href = `/api/download/${data.output_file}`; + loadGallery(); + }, 1500); + + } else if (data.status === "failed") { + appendLogLine(`Critical Error: ${data.error}`, "error"); + alert(`Upscaling job failed: ${data.error}`); + } else if (data.status === "cancelled") { + appendLogLine("Process aborted by user.", "error"); + alert("Upscaling job cancelled."); + window.location.reload(); + } + loadQueue(); +} + +let vprepScrubbing = false; + +function initVideoPreviewControls(vidOriginal, vidUpscaled) { + const playBtn = document.getElementById("vprep-play-btn"); + const scrubber = document.getElementById("vprep-scrubber"); + const timeCurrent = document.getElementById("vprep-time-current"); + const timeDuration = document.getElementById("vprep-time-duration"); + + // Play/Pause button click + playBtn.onclick = () => { + if (vidOriginal.paused) { + vidOriginal.play(); + vidUpscaled.play(); + playBtn.innerHTML = ``; + } else { + vidOriginal.pause(); + vidUpscaled.pause(); + playBtn.innerHTML = ``; + } + }; + + // Time Sync logic + vidOriginal.onplay = () => { vidUpscaled.play(); playBtn.innerHTML = ``; }; + vidOriginal.onpause = () => { vidUpscaled.pause(); playBtn.innerHTML = ``; }; + + vidOriginal.onloadedmetadata = () => { + scrubber.max = vidOriginal.duration || 5; + timeDuration.textContent = formatTime(vidOriginal.duration || 5); + }; + + vidOriginal.ontimeupdate = () => { + if (!vprepScrubbing) { + scrubber.value = vidOriginal.currentTime; + timeCurrent.textContent = formatTime(vidOriginal.currentTime); + } + + // Sync check + const diff = Math.abs(vidOriginal.currentTime - vidUpscaled.currentTime); + if (diff > 0.15 && !vidOriginal.seeking && !vidUpscaled.seeking) { + vidUpscaled.currentTime = vidOriginal.currentTime; + } + }; + + // Scrubber drag seeking + scrubber.onmousedown = () => { vprepScrubbing = true; }; + scrubber.onmouseup = () => { + vprepScrubbing = false; + vidOriginal.currentTime = parseFloat(scrubber.value); + vidUpscaled.currentTime = parseFloat(scrubber.value); + }; + scrubber.oninput = () => { + timeCurrent.textContent = formatTime(parseFloat(scrubber.value)); + }; + + // Mobile touch scrubber events + scrubber.ontouchstart = () => { vprepScrubbing = true; }; + scrubber.ontouchend = () => { + vprepScrubbing = false; + vidOriginal.currentTime = parseFloat(scrubber.value); + vidUpscaled.currentTime = parseFloat(scrubber.value); + }; +} + +let pollingInterval = null; +function startFallbackPolling(jobId) { + if (pollingInterval) clearInterval(pollingInterval); + appendLogLine("Fallback: WebSockets offline. Switched to REST polling...", "warning"); + + pollingInterval = setInterval(async () => { + try { + const res = await fetch(`/api/upscale/status/${jobId}`); + if (res.ok) { + const data = await res.json(); + updateProgressUI(data); + if (data.status === "completed" || data.status === "failed" || data.status === "cancelled") { + clearInterval(pollingInterval); + } + } + } catch (err) { + console.error("Polling error:", err); + } + }, 1000); +} + +cancelUpscaleBtn.addEventListener("click", async () => { + if (!currentJobId) return; + + if (confirm("Are you sure you want to abort the upscaling process? All progress will be lost.")) { + try { + const res = await fetch(`/api/upscale/cancel/${currentJobId}`, { method: "POST" }); + if (res.ok) { + appendLogLine("Sending abort command to worker...", "error"); + } + } catch (err) { + console.error("Error cancelling job:", err); + } + } +}); + +async function checkActiveJobs() { + try { + const res = await fetch("/api/jobs"); + if (!res.ok) return; + + const jobs = await res.json(); + const activeJob = jobs.find(job => + ["queued", "analyzing", "extracting", "upscaling", "assembling"].includes(job.status) + ); + + if (activeJob) { + currentJobId = activeJob.job_id; + + document.querySelectorAll(".step-container").forEach(el => el.classList.remove("active")); + stepProgress.classList.add("active"); + jobIdDisplay.textContent = currentJobId; + + connectProgressWebSocket(currentJobId); + } + } catch (err) { + console.error("Error checking active jobs:", err); + } +} + + +/* ---------------------------------------------------- + 7. Synced Playback Modal & Control Handlers + ---------------------------------------------------- */ +let isScrubbing = false; +let syncInterval = null; + +function formatTime(seconds) { + if (isNaN(seconds)) return "00:00"; + const mins = Math.floor(seconds / 60); + const secs = Math.floor(seconds % 60); + return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; +} + +function openVideoComparisonModal(originalSrc, upscaledSrc) { + modalVideoOriginal.src = originalSrc; + modalVideoUpscaled.src = upscaledSrc; + + modalVideoOriginal.load(); + modalVideoUpscaled.load(); + + videoModal.style.display = "flex"; + document.body.style.overflow = "hidden"; + + modalPlayBtn.innerHTML = ``; + modalTimeSlider.value = 0; + modalTimeCurrent.textContent = "00:00"; + modalTimeDuration.textContent = "00:00"; + + modalVideoOriginal.onloadedmetadata = () => { + modalTimeSlider.max = modalVideoOriginal.duration; + modalTimeDuration.textContent = formatTime(modalVideoOriginal.duration); + }; + + // Strict periodic sync check + syncInterval = setInterval(() => { + if (!modalVideoOriginal.paused && !modalVideoOriginal.seeking && !modalVideoUpscaled.seeking) { + const diff = Math.abs(modalVideoOriginal.currentTime - modalVideoUpscaled.currentTime); + if (diff > 0.15) { + console.log(`Syncing video channels: diff was ${diff}s`); + modalVideoUpscaled.currentTime = modalVideoOriginal.currentTime; + } + } + if (!isScrubbing && !modalVideoOriginal.paused) { + modalTimeSlider.value = modalVideoOriginal.currentTime; + modalTimeCurrent.textContent = formatTime(modalVideoOriginal.currentTime); + } + }, 100); +} + +function closeVideoModal() { + if (syncInterval) clearInterval(syncInterval); + modalVideoOriginal.pause(); + modalVideoUpscaled.pause(); + modalVideoOriginal.removeAttribute("src"); + modalVideoUpscaled.removeAttribute("src"); + modalVideoOriginal.load(); + modalVideoUpscaled.load(); + videoModal.style.display = "none"; + document.body.style.overflow = ""; +} + +modalCloseBtn.addEventListener("click", closeVideoModal); +videoModal.addEventListener("click", (e) => { + if (e.target === videoModal) closeVideoModal(); +}); + +modalPlayBtn.addEventListener("click", () => { + if (modalVideoOriginal.paused) { + modalVideoOriginal.play(); + modalVideoUpscaled.play(); + modalPlayBtn.innerHTML = ``; + } else { + modalVideoOriginal.pause(); + modalVideoUpscaled.pause(); + modalPlayBtn.innerHTML = ``; + } +}); + +modalTimeSlider.addEventListener("mousedown", () => { isScrubbing = true; }); +modalTimeSlider.addEventListener("mouseup", () => { isScrubbing = false; }); +modalTimeSlider.addEventListener("input", (e) => { + const val = parseFloat(e.target.value); + modalVideoOriginal.currentTime = val; + modalVideoUpscaled.currentTime = val; + modalTimeCurrent.textContent = formatTime(val); +}); + +modalMuteBtn.addEventListener("click", () => { + const isMuted = modalVideoOriginal.muted; + modalVideoOriginal.muted = !isMuted; + modalVideoUpscaled.muted = !isMuted; + modalMuteBtn.innerHTML = isMuted ? `` : ``; +}); + + +/* ---------------------------------------------------- + 8. Finished/Completed Runs Direct Comparison Launch + ---------------------------------------------------- */ +if (finishedPlayComparisonBtn) { + finishedPlayComparisonBtn.addEventListener("click", async () => { + if (!currentJobId) return; + try { + const res = await fetch("/api/jobs"); + if (!res.ok) return; + const jobs = await res.json(); + const job = jobs.find(j => j.job_id === currentJobId); + if (job) { + const originalFilename = job.video_path.split("/").pop(); + const originalUrl = `/api/uploads/${originalFilename}`; + const upscaledUrl = `/api/download/${job.output_file.split("/").pop()}`; + openVideoComparisonModal(originalUrl, upscaledUrl); + } + } catch (err) { + console.error("Comparison playback trigger error:", err); + } + }); +} + + +/* ---------------------------------------------------- + 9. Visual Outputs Gallery & Delete Action + ---------------------------------------------------- */ +async function loadGallery() { + const galleryGrid = document.getElementById("gallery-grid"); + if (!galleryGrid) return; + + try { + const [outputsRes, jobsRes] = await Promise.all([ + fetch("/api/outputs"), + fetch("/api/jobs") + ]); + + if (!outputsRes.ok || !jobsRes.ok) return; + + const outputs = await outputsRes.json(); + const jobs = await jobsRes.json(); + + if (outputs.length === 0) { + galleryGrid.innerHTML = ` + + `; + return; + } + + galleryGrid.innerHTML = ""; + + outputs.forEach(file => { + const basename = file.filename.replace("upscaled_", ""); + const jobId = basename.split(".")[0]; + const matchingJob = jobs.find(j => j.job_id === jobId); + + const card = document.createElement("div"); + card.className = "gallery-card"; + + let modelInfo = "AI Upscaled"; + let originalFilename = null; + let originalUrl = null; + let upscaledUrl = file.url; + + if (matchingJob) { + modelInfo = `${matchingJob.model} (${matchingJob.scale}x)`; + originalFilename = matchingJob.video_path.split("/").pop(); + originalUrl = `/api/uploads/${originalFilename}`; + } + + card.innerHTML = ` + + + + `; + + const playOverlay = card.querySelector(".play-overlay"); + const playCompareBtn = card.querySelector(".btn-play-compare"); + + const playAction = () => { + if (originalUrl) { + openVideoComparisonModal(originalUrl, upscaledUrl); + } else { + alert("Original video source file not found on disk. Performing upscaled output playback comparison."); + openVideoComparisonModal(upscaledUrl, upscaledUrl); + } + }; + + playOverlay.addEventListener("click", playAction); + playCompareBtn.addEventListener("click", playAction); + + const deleteBtn = card.querySelector(".btn-delete"); + deleteBtn.addEventListener("click", async () => { + if (confirm(`Are you sure you want to delete ${file.filename}? This will remove all related uploads, outputs, and logs permanently.`)) { + try { + let delSuccess = false; + if (matchingJob) { + const delJobRes = await fetch(`/api/jobs/${matchingJob.job_id}`, { + method: "DELETE" + }); + delSuccess = delJobRes.ok; + } else { + const delOutputRes = await fetch(`/api/outputs/delete/${file.filename}`, { + method: "DELETE" + }); + delSuccess = delOutputRes.ok; + } + + if (delSuccess) { + loadGallery(); + } else { + alert("Failed to delete video file and related resources."); + } + } catch (err) { + console.error("Delete error:", err); + } + } + }); + + galleryGrid.appendChild(card); + }); + } catch (err) { + console.error("Error loading gallery:", err); + } +} + +async function loadQueue() { + const queueList = document.getElementById("queue-list"); + if (!queueList) return; + + try { + const res = await fetch("/api/jobs"); + if (!res.ok) return; + + const jobs = await res.json(); + + const displayJobs = jobs.filter(job => + ["queued", "analyzing", "extracting", "upscaling", "assembling", "failed", "cancelled"].includes(job.status) + ); + + if (displayJobs.length === 0) { + queueList.innerHTML = ` +
+ +

No active or queued jobs at the moment.

+
+ `; + return; + } + + queueList.innerHTML = ""; + + displayJobs.forEach(job => { + const item = document.createElement("div"); + item.className = "queue-item"; + + const titleLabel = job.is_preview ? `Preview (5s) - ${job.job_id.substring(0, 8)}...` : `Job - ${job.job_id.substring(0, 8)}...`; + const modelLabel = job.model; + const scaleLabel = `${job.scale}x`; + const progress = Math.round(job.progress || 0); + + let metaHtml = ` + Model: ${modelLabel} (${scaleLabel}) + Source: ${job.video_path.split('/').pop()} + `; + + if (job.status === "failed" && job.error) { + metaHtml += ` Error: ${job.error}`; + } else if (job.status !== "queued" && job.status !== "failed" && job.status !== "cancelled") { + metaHtml += ` ETA: ${job.eta || 'Calculating...'}`; + } + + let actionsHtml = ""; + if (["queued", "analyzing", "extracting", "upscaling", "assembling"].includes(job.status)) { + actionsHtml = ` + + `; + } else { + actionsHtml = ` + + `; + } + + const showProgress = ["analyzing", "extracting", "upscaling", "assembling"].includes(job.status); + const progressStyle = showProgress ? "display: block;" : "display: none;"; + + item.innerHTML = ` +
+
+ ${titleLabel} + ${job.status} +
+
+ ${metaHtml} +
+
+
+
+
+
+
+ ${actionsHtml} +
+
+ `; + + const abortBtn = item.querySelector(".btn-abort-job"); + if (abortBtn) { + abortBtn.addEventListener("click", async () => { + if (confirm("Are you sure you want to abort this upscaling job?")) { + try { + const abortRes = await fetch(`/api/upscale/cancel/${job.job_id}`, { method: "POST" }); + if (abortRes.ok) { + loadQueue(); + } + } catch (err) { + console.error("Error aborting job:", err); + } + } + }); + } + + const deleteBtn = item.querySelector(".btn-delete-job"); + if (deleteBtn) { + deleteBtn.addEventListener("click", async () => { + if (confirm("Are you sure you want to clear this job from history?")) { + try { + const delRes = await fetch(`/api/jobs/${job.job_id}`, { method: "DELETE" }); + if (delRes.ok) { + loadQueue(); + loadGallery(); + } + } catch (err) { + console.error("Error clearing job:", err); + } + } + }); + } + + queueList.appendChild(item); + }); + } catch (err) { + console.error("Error loading queue:", err); + } +} + +const refreshGalleryBtn = document.getElementById("refresh-gallery-btn"); +if (refreshGalleryBtn) { + refreshGalleryBtn.addEventListener("click", loadGallery); +} + +const refreshQueueBtn = document.getElementById("refresh-queue-btn"); +if (refreshQueueBtn) { + refreshQueueBtn.addEventListener("click", loadQueue); +} + +const purgeAllBtn = document.getElementById("purge-all-btn"); +if (purgeAllBtn) { + purgeAllBtn.addEventListener("click", async () => { + if (confirm("⚠️ WARNING: This will permanently delete ALL uploaded source videos, completed outputs, temp frames, and history logs. Are you sure you want to proceed?")) { + try { + const res = await fetch("/api/jobs/purge-all", { + method: "POST" + }); + if (res.ok) { + alert("System files purged successfully!"); + loadGallery(); + } else { + alert("Failed to purge system files."); + } + } catch (err) { + console.error("Purge all error:", err); + } + } + }); +} + + +/* ---------------------------------------------------- + 10. Core Setup & Models Loading + ---------------------------------------------------- */ +const standardModelNames = { + "realesr-animevideov3": "Real-ESRGAN Anime Video V3 (Fast / Anime & Video)", + "realesrgan-x4plus": "Real-ESRGAN X4 Plus (Ultra Quality / Real World)", + "realesrgan-x4plus-anime": "Real-ESRGAN X4 Plus Anime (Ultra Quality / Illustration)", + "realesrnet-x4plus": "Real-ESRNet X4 Plus (Alternate / Real World)" +}; + +async function loadModels() { + try { + const res = await fetch("/api/models"); + if (!res.ok) return; + + const models = await res.json(); + if (models && models.length > 0) { + modelSelect.innerHTML = ""; + + models.forEach(model => { + const opt = document.createElement("option"); + opt.value = model; + opt.textContent = standardModelNames[model] || `Custom Model: ${model}`; + if (model === "realesr-animevideov3") { + opt.selected = true; + } + modelSelect.appendChild(opt); + }); + + modelSelect.dispatchEvent(new Event("change")); + } + } catch (err) { + console.error("Error loading models list:", err); + } +} + +async function initializeApp() { + await loadModels(); + await checkActiveJobs(); + await loadGallery(); // Load enhancement gallery at page load + await loadQueue(); // Load active jobs queue at page load +} + +initializeApp(); diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..f33d67a --- /dev/null +++ b/static/index.html @@ -0,0 +1,576 @@ + + + + + + Antigravity AI Video Upscaler + + + + + +
+ +
+
+
▲
+
+

ANTIGRAVITY // UPSCALE

+

Open Source AI Video Enhancer

+
+
+
+
+ + +
+
+
+ GPU Active: Quadro P2000 (Vulkan) +
+
+
+ +
+ +
+
+
+ + +

Drag & Drop Video File

+

Supports MP4, MKV, AVI, MOV, WEBM (Max 500MB recommended for local upscaling)

+ +
+
+
+ + +
+
+ +
+ +
+

Video Source Info

+
+
+ File Name + - +
+
+ Size + - +
+
+ + +
+
+
+ Video Stream #0 + +
+
+
+
+ Codec + - +
+
+ Resolution + - +
+
+ Frame Rate + - +
+
+ Duration + - +
+
+ Total Frames + - +
+
+ Aspect Ratio + - +
+
+
+
+
+
+ Audio Stream #1 + +
+
+
+
+ Codec + - +
+
+ Channels + - +
+
+ Sample Rate + - +
+
+ Bitrate + - +
+
+
+
+
+
+ + +
+

Video Trimming

+

Specify range to upscale only a portion of the video.

+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ + +
+

Upscaling Profile

+ + +
+ + +
+ + +
+ +
+ +
+
+ + +
+ Advanced Options + +
+ + +
+ +
+ + +
+ + +
+ +
+ +
+

+ Halves automatically in case of Vulkan VRAM allocation faults. +

+
+ + +
+ +
+ +
+

+ 0 (lossless) to 51 (worst). Default 18 (visually pristine). +

+
+ + +
+ + +
+ + +
+ + +
+ + +
+ Pre-Filters & Enhancing +
+ + + +
+
+ + +
+ + +
+ + +
+ +
+ + +

Select both model files to load into realesrgan

+ No files selected +
+ +
+ + +
+
+ Preserve Audio + Copy audio streams into upscaled video +
+ +
+
+ + + +
+
+ + +
+
+

Clarity Preview

+ +
+ + +
+
+ +
+ + +
+
+ +
+ + +
+ +
+ +

Clarity Preview Frame

+

Extracts a single frame at the chosen timestamp and runs the AI model to show side-by-side comparative clarity enhancement.

+

Click "Render Preview Frame" above to generate the comparative view.

+
+ + + + + + + + + + + +
+
+

Orchestrating Vulkan GPU...

+ +

Extracting and upscaling frame. Please wait...

+
+
+
+
+
+ + +
+
+
+
+

Upscaling Video Pipeline

+

Job ID: -

+
+ Queued +
+ + +
+
+ Progress + 0% +
+
+
+
+
+ + +
+
+ Status + Queued +
+
+ Processed Frames + 0 / 0 +
+
+ Estimated ETA + Calculating... +
+
+ + +
+

Pipeline Live Activity Logs

+
+
Waiting for worker thread...
+
+
+ + +
+ +
+
+
+ + +
+
+
+ +
+

Video Enhancement Completed!

+

+ Your video was successfully upscaled and optimized using the Real-ESRGAN Vulkan backend model. Original audio streams have been merged. +

+ +
+ + Download Upscaled Video + + + +
+
+
+ + +
+
+

Active Jobs & Pipeline Queue

+ +
+

Monitor running and queued jobs in the queue pipeline. Preview jobs are marked as well.

+ +
+ +
+ +

No active or queued jobs at the moment.

+
+
+
+ + + +
+
+ + + + + + + + diff --git a/static/styles.css b/static/styles.css new file mode 100644 index 0000000..0ba568f --- /dev/null +++ b/static/styles.css @@ -0,0 +1,1499 @@ +@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&family=Space+Grotesk:wght@400;500;600;700&display=swap'); + +:root { + --bg-dark: #07080b; + --card-bg: rgba(16, 18, 23, 0.7); + --border-color: rgba(255, 255, 255, 0.06); + --border-glow: rgba(0, 240, 255, 0.15); + + --primary: #00f0ff; + --primary-glow: rgba(0, 240, 255, 0.4); + --secondary: #bd00ff; + --secondary-glow: rgba(189, 0, 255, 0.4); + --gradient: linear-gradient(135deg, var(--primary), var(--secondary)); + + --text-main: #f1f5f9; + --text-muted: #8a99ad; + --text-dim: #54657a; + + --success: #00ff87; + --warning: #ffb800; + --danger: #ff0055; + + --font-heading: 'Space Grotesk', sans-serif; + --font-body: 'Outfit', sans-serif; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + background-color: var(--bg-dark); + color: var(--text-main); + font-family: var(--font-body); + min-height: 100vh; + overflow-x: hidden; + background-image: + radial-gradient(circle at 10% 20%, rgba(0, 240, 255, 0.03) 0%, transparent 40%), + radial-gradient(circle at 90% 80%, rgba(189, 0, 255, 0.04) 0%, transparent 40%); +} + +.app-container { + max-width: 1200px; + margin: 0 auto; + padding: 2rem 1.5rem; +} + +header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 3rem; + border-bottom: 1px solid var(--border-color); + padding-bottom: 1.5rem; +} + +.logo-container { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.logo-icon { + width: 40px; + height: 40px; + background: var(--gradient); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + font-weight: 800; + font-family: var(--font-heading); + font-size: 1.5rem; + color: var(--bg-dark); + box-shadow: 0 0 20px var(--primary-glow); +} + +.logo-text h1 { + font-family: var(--font-heading); + font-size: 1.5rem; + font-weight: 700; + letter-spacing: 2px; + background: var(--gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.logo-text p { + font-size: 0.75rem; + color: var(--text-muted); + letter-spacing: 1px; + text-transform: uppercase; +} + +.gpu-badge { + background: rgba(255, 255, 255, 0.03); + border: 1px solid var(--border-color); + padding: 0.5rem 1rem; + border-radius: 50px; + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.85rem; +} + +.gpu-dot { + width: 8px; + height: 8px; + background: var(--success); + border-radius: 50%; + box-shadow: 0 0 8px var(--success); + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0% { transform: scale(0.9); opacity: 0.6; } + 50% { transform: scale(1.1); opacity: 1; box-shadow: 0 0 12px var(--success); } + 100% { transform: scale(0.9); opacity: 0.6; } +} + +/* Glassmorphism Card Wrapper */ +.glass-card { + background: var(--card-bg); + border: 1px solid var(--border-color); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border-radius: 24px; + padding: 2.5rem; + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + overflow: hidden; +} + +.glass-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 3px; + background: var(--gradient); + opacity: 0.7; +} + +.step-container { + display: none; +} + +.step-container.active { + display: block; + animation: fadeIn 0.5s ease-out; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +/* Step 1: Drag & Drop Styles */ +.upload-area { + border: 2px dashed rgba(255, 255, 255, 0.15); + border-radius: 20px; + padding: 4rem 2rem; + text-align: center; + cursor: pointer; + transition: all 0.3s ease; + background: rgba(255, 255, 255, 0.01); +} + +.upload-area:hover, .upload-area.drag-over { + border-color: var(--primary); + background: rgba(0, 240, 255, 0.02); + box-shadow: inset 0 0 20px rgba(0, 240, 255, 0.05); +} + +.upload-icon { + font-size: 3.5rem; + margin-bottom: 1.5rem; + display: inline-block; + background: var(--gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + animation: float 3s ease-in-out infinite; +} + +@keyframes float { + 0% { transform: translateY(0px); } + 50% { transform: translateY(-8px); } + 100% { transform: translateY(0px); } +} + +.upload-area h3 { + font-family: var(--font-heading); + font-size: 1.35rem; + margin-bottom: 0.5rem; +} + +.upload-area p { + color: var(--text-muted); + font-size: 0.95rem; + margin-bottom: 1.5rem; +} + +.btn { + background: var(--gradient); + color: var(--bg-dark); + font-family: var(--font-heading); + font-weight: 700; + font-size: 1rem; + padding: 0.85rem 2rem; + border: none; + border-radius: 12px; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 0 20px rgba(0, 240, 255, 0.2); + display: inline-flex; + align-items: center; + gap: 0.5rem; +} + +.btn:hover { + transform: translateY(-2px); + box-shadow: 0 0 30px var(--primary-glow); +} + +.btn:active { + transform: translateY(0); +} + +.btn-secondary { + background: rgba(255, 255, 255, 0.05); + color: var(--text-main); + border: 1px solid var(--border-color); + box-shadow: none; +} + +.btn-secondary:hover { + background: rgba(255, 255, 255, 0.1); + box-shadow: none; +} + +.btn-danger { + background: var(--danger); + color: #fff; + box-shadow: 0 0 20px rgba(255, 0, 85, 0.2); +} + +.btn-danger:hover { + box-shadow: 0 0 30px rgba(255, 0, 85, 0.4); +} + +/* Step 2: Configuration & Preview Layout */ +.config-layout { + display: grid; + grid-template-columns: 1.2fr 1.8fr; + gap: 2.5rem; +} + +@media (max-width: 900px) { + .config-layout { + grid-template-columns: 1fr; + } +} + +.config-sidebar { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.meta-panel { + background: rgba(255, 255, 255, 0.02); + border: 1px solid var(--border-color); + padding: 1.5rem; + border-radius: 16px; +} + +.meta-panel h4 { + font-family: var(--font-heading); + font-size: 1.1rem; + margin-bottom: 1rem; + color: var(--primary); +} + +.meta-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + font-size: 0.9rem; +} + +.meta-item span:first-child { + display: block; + color: var(--text-muted); + font-size: 0.75rem; + text-transform: uppercase; + margin-bottom: 0.15rem; +} + +.meta-item span:last-child { + font-weight: 600; +} + +.settings-panel { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.form-group { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.form-group label { + font-size: 0.9rem; + font-weight: 600; + color: var(--text-main); + display: flex; + justify-content: space-between; +} + +.form-group label span.badge { + font-weight: normal; + color: var(--primary); + font-size: 0.8rem; + background: rgba(0, 240, 255, 0.08); + padding: 0.1rem 0.5rem; + border-radius: 4px; +} + +select { + background: rgba(255, 255, 255, 0.04); + border: 1px solid var(--border-color); + color: var(--text-main); + padding: 0.8rem 1rem; + border-radius: 10px; + font-family: var(--font-body); + font-size: 0.95rem; + cursor: pointer; + outline: none; + transition: border 0.3s; +} + +select:focus { + border-color: var(--primary); +} + +select option { + background: #0f1115; + color: var(--text-main); +} + +/* Custom sliders */ +.range-slider { + display: flex; + align-items: center; + gap: 1rem; +} + +input[type="range"] { + -webkit-appearance: none; + width: 100%; + height: 6px; + border-radius: 5px; + background: rgba(255, 255, 255, 0.1); + outline: none; +} + +input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 18px; + height: 18px; + border-radius: 50%; + background: var(--primary); + cursor: pointer; + box-shadow: 0 0 10px var(--primary-glow); + transition: transform 0.1s; +} + +input[type="range"]::-webkit-slider-thumb:hover { + transform: scale(1.2); +} + +/* Custom toggle */ +.toggle-container { + display: flex; + align-items: center; + justify-content: space-between; + background: rgba(255, 255, 255, 0.02); + border: 1px solid var(--border-color); + padding: 1rem; + border-radius: 12px; +} + +.switch { + position: relative; + display: inline-block; + width: 46px; + height: 24px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(255, 255, 255, 0.15); + transition: .4s; + border-radius: 34px; +} + +.slider:before { + position: absolute; + content: ""; + height: 18px; + width: 18px; + left: 3px; + bottom: 3px; + background-color: white; + transition: .4s; + border-radius: 50%; +} + +input:checked + .slider { + background: var(--gradient); +} + +input:checked + .slider:before { + transform: translateX(22px); +} + +/* Compare Frame Slider Component */ +.preview-panel { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.preview-header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.preview-header h3 { + font-family: var(--font-heading); + font-size: 1.35rem; +} + +.timeline-picker { + display: flex; + flex-direction: column; + gap: 0.5rem; + background: rgba(255, 255, 255, 0.02); + padding: 1rem; + border-radius: 12px; +} + +.comparison-wrapper { + position: relative; + width: 100%; + aspect-ratio: 16/9; + border-radius: 16px; + overflow: hidden; + border: 1px solid var(--border-color); + background: #000; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); +} + +.comparison-image { + width: 100%; + height: 100%; + object-fit: contain; + position: absolute; + top: 0; + left: 0; + pointer-events: none; + user-select: none; + transform: translate(var(--pan-x), var(--pan-y)) scale(var(--zoom)); + transform-origin: center center; + transition: transform 0.1s ease-out; +} + +.comparison-image.original { + z-index: 1; +} + +.comparison-image.upscaled { + z-index: 2; +} + +.slider-bar { + position: absolute; + top: 0; + bottom: 0; + left: 50%; + width: 4px; + background: #fff; + z-index: 3; + cursor: ew-resize; + box-shadow: 0 0 10px rgba(0,0,0,0.5); + transform: translateX(-50%); + pointer-events: auto; +} + +.slider-handle { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 40px; + height: 40px; + border-radius: 50%; + background: #fff; + border: 3px solid var(--primary); + box-shadow: 0 0 15px var(--primary-glow); + display: flex; + align-items: center; + justify-content: center; + cursor: ew-resize; +} + +.slider-handle::before, .slider-handle::after { + content: ''; + border: solid transparent; + border-width: 5px 6px; + position: absolute; +} + +.slider-handle::before { + border-right-color: var(--primary); + right: 22px; +} + +.slider-handle::after { + border-left-color: var(--primary); + left: 22px; +} + +.badge-orig, .badge-up { + position: absolute; + bottom: 12px; + padding: 0.35rem 0.75rem; + border-radius: 6px; + font-size: 0.75rem; + font-weight: bold; + z-index: 4; + text-transform: uppercase; + letter-spacing: 1px; + backdrop-filter: blur(4px); +} + +.badge-orig { + left: 12px; + background: rgba(0, 0, 0, 0.6); + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.badge-up { + right: 12px; + background: rgba(0, 240, 255, 0.2); + border: 1px solid var(--primary); + color: var(--primary); +} + +.preview-placeholder { + width: 100%; + aspect-ratio: 16/9; + border-radius: 16px; + border: 1px dashed rgba(255, 255, 255, 0.08); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + color: var(--text-muted); + text-align: center; + padding: 2rem; + background: rgba(255, 255, 255, 0.005); +} + +.preview-placeholder i { + font-size: 2.5rem; + margin-bottom: 1rem; + color: var(--text-dim); +} + +.preview-loading { + display: none; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(7, 8, 11, 0.85); + z-index: 5; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1rem; +} + +.spinner { + width: 48px; + height: 48px; + border: 4px solid rgba(255, 255, 255, 0.05); + border-top-color: var(--primary); + border-radius: 50%; + animation: spin 1s linear infinite; + box-shadow: 0 0 10px rgba(0, 240, 255, 0.1); +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* Step 3: Progress dashboard */ +.progress-card { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.progress-header { + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +.status-badge { + padding: 0.5rem 1rem; + border-radius: 50px; + font-size: 0.8rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 1px; +} + +.status-badge.queued { background: rgba(255, 184, 0, 0.1); border: 1px solid var(--warning); color: var(--warning); } +.status-badge.extracting { background: rgba(189, 0, 255, 0.15); border: 1px solid var(--secondary); color: #e499ff; } +.status-badge.upscaling { background: rgba(0, 240, 255, 0.1); border: 1px solid var(--primary); color: var(--primary); } +.status-badge.assembling { background: rgba(0, 240, 255, 0.1); border: 1px solid var(--primary); color: var(--primary); } +.status-badge.completed { background: rgba(0, 255, 135, 0.1); border: 1px solid var(--success); color: var(--success); } +.status-badge.failed { background: rgba(255, 0, 85, 0.1); border: 1px solid var(--danger); color: var(--danger); } + +.bar-container { + width: 100%; + height: 16px; + background: rgba(255, 255, 255, 0.03); + border: 1px solid var(--border-color); + border-radius: 10px; + overflow: hidden; + position: relative; + box-shadow: inset 0 2px 4px rgba(0,0,0,0.5); +} + +.bar-fill { + height: 100%; + width: 0%; + background: var(--gradient); + border-radius: 10px; + box-shadow: 0 0 10px var(--primary-glow); + transition: width 0.4s ease; + position: relative; + overflow: hidden; +} + +.bar-fill::after { + content: ''; + position: absolute; + top: 0; left: 0; right: 0; bottom: 0; + background: linear-gradient( + 90deg, + transparent, + rgba(255,255,255,0.15), + transparent + ); + transform: translateX(-100%); + animation: shimmer 1.5s infinite; +} + +@keyframes shimmer { + 100% { transform: translateX(100%); } +} + +.progress-stats { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 1.5rem; +} + +.stat-card { + background: rgba(255, 255, 255, 0.01); + border: 1px solid var(--border-color); + padding: 1.25rem; + border-radius: 14px; +} + +.stat-card span:first-child { + display: block; + font-size: 0.75rem; + color: var(--text-muted); + text-transform: uppercase; + margin-bottom: 0.25rem; + letter-spacing: 1px; +} + +.stat-card span:last-child { + font-family: var(--font-heading); + font-size: 1.35rem; + font-weight: 700; +} + +.log-panel { + background: #040508; + border: 1px solid var(--border-color); + border-radius: 12px; + padding: 1rem; + font-family: 'Space Grotesk', monospace; + font-size: 0.85rem; + color: #a5b4fc; + height: 180px; + overflow-y: auto; +} + +.log-line { + margin-bottom: 0.35rem; +} + +.log-line.error { color: var(--danger); } +.log-line.success { color: var(--success); } + +/* Step 4: Finished Layout */ +.finished-card { + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + gap: 1.5rem; + padding: 4rem 2rem; +} + +.success-icon { + width: 80px; + height: 80px; + background: rgba(0, 255, 135, 0.1); + border: 2px solid var(--success); + color: var(--success); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 3rem; + box-shadow: 0 0 30px rgba(0, 255, 135, 0.2); + animation: successPulse 2s infinite; +} + +@keyframes successPulse { + 0% { transform: scale(1); box-shadow: 0 0 30px rgba(0, 255, 135, 0.2); } + 50% { transform: scale(1.05); box-shadow: 0 0 50px rgba(0, 255, 135, 0.4); } + 100% { transform: scale(1); box-shadow: 0 0 30px rgba(0, 255, 135, 0.2); } +} + +.finished-card h2 { + font-family: var(--font-heading); + font-size: 2rem; + font-weight: 700; +} + +.action-buttons { + display: flex; + gap: 1rem; + margin-top: 1.5rem; +} + +/* ---------------------------------------------------- + 5. Dynamic Theme Colors + ---------------------------------------------------- */ +body.theme-oled { + --bg-dark: #000000; + --card-bg: rgba(10, 10, 10, 0.85); + --border-color: rgba(255, 255, 255, 0.08); + --border-glow: rgba(168, 85, 247, 0.15); + --primary: #a855f7; + --primary-glow: rgba(168, 85, 247, 0.4); + --secondary: #ec4899; + --secondary-glow: rgba(236, 72, 153, 0.4); + --gradient: linear-gradient(135deg, var(--primary), var(--secondary)); + --text-main: #f8fafc; + --text-muted: #94a3b8; + background-image: + radial-gradient(circle at 10% 20%, rgba(168, 85, 247, 0.03) 0%, transparent 40%), + radial-gradient(circle at 90% 80%, rgba(236, 72, 153, 0.03) 0%, transparent 40%); +} + +body.theme-cyberpunk { + --bg-dark: #07080b; + --card-bg: rgba(16, 18, 23, 0.7); + --border-color: rgba(255, 255, 255, 0.06); + --border-glow: rgba(0, 240, 255, 0.15); + --primary: #00f0ff; + --primary-glow: rgba(0, 240, 255, 0.4); + --secondary: #bd00ff; + --secondary-glow: rgba(189, 0, 255, 0.4); + --gradient: linear-gradient(135deg, var(--primary), var(--secondary)); + --text-main: #f1f5f9; + --text-muted: #8a99ad; + background-image: + radial-gradient(circle at 10% 20%, rgba(0, 240, 255, 0.03) 0%, transparent 40%), + radial-gradient(circle at 90% 80%, rgba(189, 0, 255, 0.04) 0%, transparent 40%); +} + +body.theme-slate { + --bg-dark: #0f172a; + --card-bg: rgba(30, 41, 59, 0.75); + --border-color: rgba(255, 255, 255, 0.08); + --border-glow: rgba(56, 189, 248, 0.1); + --primary: #38bdf8; + --primary-glow: rgba(56, 189, 248, 0.35); + --secondary: #818cf8; + --secondary-glow: rgba(129, 140, 248, 0.35); + --gradient: linear-gradient(135deg, var(--primary), var(--secondary)); + --text-main: #f1f5f9; + --text-muted: #94a3b8; + background-image: + radial-gradient(circle at 10% 20%, rgba(56, 189, 248, 0.02) 0%, transparent 45%), + radial-gradient(circle at 90% 80%, rgba(129, 140, 248, 0.03) 0%, transparent 45%); +} + +.header-actions { + display: flex; + align-items: center; + gap: 1rem; +} + +.theme-selector { + display: flex; + align-items: center; + gap: 0.5rem; + background: rgba(255, 255, 255, 0.03); + border: 1px solid var(--border-color); + padding: 0.25rem 0.75rem; + border-radius: 50px; +} + +.theme-selector label { + font-size: 0.8rem; + color: var(--text-muted); + font-weight: 500; + display: flex; + align-items: center; + gap: 0.25rem; +} + +.theme-selector select { + background: transparent; + border: none; + color: var(--text-main); + font-size: 0.8rem; + padding: 0.15rem 0.5rem 0.15rem 0; + font-weight: 600; + cursor: pointer; + outline: none; + box-shadow: none; +} + +/* ---------------------------------------------------- + 6. Collapsible Advanced Settings & Trimming + ---------------------------------------------------- */ +.advanced-settings-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 0; + border-top: 1px solid var(--border-color); + margin-top: 1.5rem; + cursor: pointer; + font-family: var(--font-heading); + font-weight: 700; + color: var(--text-main); + transition: color 0.2s; + user-select: none; +} + +.advanced-settings-header:hover { + color: var(--primary); +} + +.advanced-settings-header i { + transition: transform 0.2s ease; +} + +.advanced-settings-header.open i { + transform: rotate(180deg); +} + +.advanced-settings-content { + display: none; + flex-direction: column; + gap: 1.25rem; + padding-top: 1rem; + border-top: 1px dashed var(--border-color); + animation: fadeIn 0.3s ease-out; +} + +.advanced-settings-content.open { + display: flex; +} + +.trimming-panel { + background: rgba(255, 255, 255, 0.02); + border: 1px solid var(--border-color); + padding: 1.5rem; + border-radius: 16px; + margin-top: 1rem; +} + +.trimming-panel h4 { + color: var(--primary); + margin-bottom: 0.25rem; +} + +.trim-inputs-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + margin-top: 1rem; +} + +/* Checkboxes and Pre-filters */ +.filter-group { + display: flex; + flex-direction: column; + gap: 0.5rem; + background: rgba(255, 255, 255, 0.01); + border: 1px solid var(--border-color); + padding: 1rem; + border-radius: 12px; +} + +.filter-checkboxes { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.75rem; + margin-top: 0.25rem; +} + +.checkbox-container { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.85rem; + cursor: pointer; + user-select: none; +} + +.checkbox-container input { + cursor: pointer; +} + +/* Custom Model Upload Area */ +.model-upload-zone { + border: 1px dashed rgba(255, 255, 255, 0.15); + border-radius: 12px; + padding: 1.25rem; + text-align: center; + background: rgba(255, 255, 255, 0.005); + cursor: pointer; + transition: all 0.2s ease; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; +} + +.model-upload-zone:hover { + border-color: var(--primary); + background: rgba(0, 240, 255, 0.01); +} + +.model-upload-zone i { + font-size: 1.75rem; + color: var(--text-dim); +} + +.model-upload-zone p { + font-size: 0.75rem; + color: var(--text-muted); +} + +.upload-model-btn-container { + display: flex; + justify-content: flex-end; + margin-top: 0.5rem; +} + +.btn-small { + padding: 0.5rem 1rem !important; + font-size: 0.85rem !important; + border-radius: 8px !important; +} + +/* ---------------------------------------------------- + 7. Zoom & Pan Previews Sync + ---------------------------------------------------- */ +.upscaled-wrapper { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + overflow: hidden; + z-index: 2; + clip-path: inset(0 0 0 50%); + pointer-events: none; +} + +.zoom-pan-bar { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 1rem; + background: rgba(255, 255, 255, 0.01); + border: 1px solid var(--border-color); + padding: 1rem; + border-radius: 12px; + margin-top: 1rem; +} + +.zoom-control-item { + display: flex; + flex-direction: column; + gap: 0.25rem; + flex: 1; + min-width: 120px; +} + +.zoom-control-item label { + font-size: 0.75rem; + color: var(--text-muted); + font-weight: 500; + display: flex; + justify-content: space-between; +} + +.zoom-control-item label span { + color: var(--primary); + font-weight: 600; +} + +/* ---------------------------------------------------- + 8. Stream Accordions & Detailed Info + ---------------------------------------------------- */ +.streams-accordions { + display: flex; + flex-direction: column; + gap: 0.5rem; + margin-top: 1rem; +} + +.accordion-item { + border: 1px solid var(--border-color); + background: rgba(255, 255, 255, 0.01); + border-radius: 10px; + overflow: hidden; +} + +.accordion-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.75rem 1rem; + cursor: pointer; + font-weight: 600; + font-size: 0.85rem; + background: rgba(255, 255, 255, 0.02); + transition: background 0.2s, color 0.2s; + user-select: none; +} + +.accordion-header:hover { + background: rgba(255, 255, 255, 0.04); + color: var(--primary); +} + +.accordion-header .toggle-icon { + font-size: 0.75rem; + transition: transform 0.2s ease; +} + +.accordion-item.open .accordion-header .toggle-icon { + transform: rotate(180deg); +} + +.accordion-content { + display: none; + padding: 1rem; + border-top: 1px dashed var(--border-color); + background: rgba(0, 0, 0, 0.2); + animation: slideDown 0.2s ease-out; +} + +.accordion-item.open .accordion-content { + display: block; +} + +.secondary-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.75rem; +} + +.secondary-grid .meta-item { + border-bottom: 1px solid rgba(255, 255, 255, 0.03); + padding-bottom: 0.5rem; +} + +.secondary-grid .meta-item:last-child, +.secondary-grid .meta-item:nth-last-child(2) { + border-bottom: none; + padding-bottom: 0; +} + +/* ---------------------------------------------------- + 9. Visual Outputs Gallery + ---------------------------------------------------- */ +.gallery-section { + position: relative; + border-top: 1px solid var(--border-color); + padding-top: 2rem; +} + +.gallery-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.5rem; +} + +.gallery-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); + gap: 1.5rem; + margin-top: 1.5rem; +} + +.gallery-card { + background: var(--card-bg); + border: 1px solid var(--border-color); + border-radius: 16px; + padding: 1.25rem; + display: flex; + flex-direction: column; + gap: 1rem; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); +} + +.gallery-card:hover { + transform: translateY(-4px); + border-color: var(--primary); + box-shadow: 0 10px 25px var(--border-glow); +} + +.gallery-thumbnail { + width: 100%; + aspect-ratio: 16/9; + background: #040508; + border-radius: 10px; + display: flex; + align-items: center; + justify-content: center; + font-size: 2.25rem; + color: var(--text-dim); + border: 1px solid rgba(255, 255, 255, 0.03); + position: relative; + overflow: hidden; +} + +.gallery-thumbnail .play-overlay { + position: absolute; + top: 0; left: 0; width: 100%; height: 100%; + background: rgba(0, 0, 0, 0.4); + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 0.2s; + font-size: 2.5rem; + color: var(--primary); + cursor: pointer; +} + +.gallery-card:hover .gallery-thumbnail .play-overlay { + opacity: 1; +} + +.gallery-info { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.gallery-info h4 { + font-size: 0.95rem; + font-weight: 600; + color: var(--text-main); + word-break: break-all; +} + +.gallery-info p { + font-size: 0.75rem; + color: var(--text-muted); +} + +.gallery-actions { + display: flex; + gap: 0.5rem; + margin-top: auto; +} + +.gallery-actions .btn { + padding: 0.5rem 0.75rem; + font-size: 0.8rem; + border-radius: 8px; + flex: 1; + justify-content: center; +} + +.gallery-actions .btn-danger { + flex: 0 0 38px; + padding: 0 !important; + display: flex; + align-items: center; + justify-content: center; + border-radius: 8px !important; +} + +.gallery-empty-state { + grid-column: 1 / -1; + text-align: center; + padding: 4rem 1rem; + color: var(--text-muted); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 0.75rem; + background: rgba(255, 255, 255, 0.005); + border: 1px dashed var(--border-color); + border-radius: 16px; +} + +.gallery-empty-state i { + font-size: 2.5rem; + color: var(--text-dim); +} + +/* ---------------------------------------------------- + 10. Synced Playback Modal + ---------------------------------------------------- */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.92); + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; + padding: 2rem; + animation: fadeIn 0.25s ease-out; +} + +.modal-card { + background: #08090d; + border: 1px solid var(--border-color); + border-radius: 24px; + width: 100%; + max-width: 1100px; + box-shadow: 0 25px 50px rgba(0, 0, 0, 0.7); + display: flex; + flex-direction: column; + overflow: hidden; + position: relative; + max-height: 90vh; +} + +.modal-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 3px; + background: var(--gradient); +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1.25rem 1.75rem; + border-bottom: 1px solid var(--border-color); +} + +.modal-header h3 { + font-family: var(--font-heading); + font-size: 1.2rem; + color: var(--text-main); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.close-btn { + background: transparent; + border: none; + color: var(--text-muted); + font-size: 2.25rem; + cursor: pointer; + transition: color 0.2s; + line-height: 1; +} + +.close-btn:hover { + color: var(--danger); +} + +.modal-body { + padding: 1.75rem; + display: flex; + flex-direction: column; + gap: 1.5rem; + overflow-y: auto; +} + +.video-compare-wrapper { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1.5rem; +} + +@media (max-width: 768px) { + .video-compare-wrapper { + grid-template-columns: 1fr; + } +} + +.video-container { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.video-container h4 { + font-size: 0.8rem; + text-transform: uppercase; + color: var(--text-muted); + letter-spacing: 1px; + font-family: var(--font-heading); +} + +.video-container video { + width: 100%; + aspect-ratio: 16/9; + background: #000; + border-radius: 12px; + border: 1px solid var(--border-color); + object-fit: contain; +} + +.video-sync-controls { + display: flex; + align-items: center; + gap: 1rem; + background: rgba(255, 255, 255, 0.02); + border: 1px solid var(--border-color); + padding: 0.75rem 1.25rem; + border-radius: 12px; +} + +.btn-circular { + width: 42px; + height: 42px; + border-radius: 50% !important; + padding: 0 !important; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.time-scrubber-container { + display: flex; + align-items: center; + gap: 0.75rem; + flex: 1; + font-size: 0.85rem; + font-family: var(--font-heading); +} + +.time-scrubber-container input[type="range"] { + flex: 1; +} + +@keyframes slideDown { + from { opacity: 0; transform: translateY(-5px); } + to { opacity: 1; transform: translateY(0); } +} + +/* 9. Active Jobs & Pipeline Queue Styles */ +.queue-item { + display: flex; + justify-content: space-between; + align-items: center; + background: rgba(255, 255, 255, 0.02); + border: 1px solid var(--border-color); + border-radius: 12px; + padding: 1rem; + transition: background 0.2s, border-color 0.2s; + animation: slideDown 0.3s ease-out; +} + +.queue-item:hover { + background: rgba(255, 255, 255, 0.04); + border-color: var(--primary-glow); +} + +.queue-item-details { + display: flex; + flex-direction: column; + gap: 0.25rem; + flex: 1; + margin-right: 1.5rem; +} + +.queue-item-title { + font-weight: 600; + font-size: 0.95rem; + color: var(--text-main); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.queue-item-meta { + font-size: 0.78rem; + color: var(--text-muted); + display: flex; + gap: 0.75rem; + flex-wrap: wrap; +} + +.queue-item-status-bar { + display: flex; + align-items: center; + gap: 1rem; + flex-shrink: 0; +} + +.queue-item-progress-container { + width: 120px; + height: 6px; + background: rgba(255, 255, 255, 0.1); + border-radius: 3px; + overflow: hidden; + display: none; +} + +.queue-item-progress-fill { + height: 100%; + background: var(--primary); + width: 0%; + transition: width 0.3s ease; +} + +.queue-item-actions { + display: flex; + gap: 0.5rem; + flex-shrink: 0; +} diff --git a/stop.py b/stop.py new file mode 100755 index 0000000..56c2846 --- /dev/null +++ b/stop.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +""" +stop.py — Stop the AI Video Upscaler web application. + +Usage: + python stop.py +""" + +import os +import signal +import sys +import time + +# ── Paths ──────────────────────────────────────────────────────────────────── +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +PID_FILE = os.path.join(BASE_DIR, ".uvicorn.pid") + + +def _is_running(pid: int) -> bool: + """Check whether a process with the given PID is still alive and is our server.""" + try: + os.kill(pid, 0) + except OSError: + return False + + # Check /proc/{pid}/cmdline to verify it's our server process + try: + cmdline_path = f"/proc/{pid}/cmdline" + if os.path.exists(cmdline_path): + with open(cmdline_path, "r") as f: + cmdline = f.read() + # Check for indicators of our server + return "uvicorn" in cmdline or "app.main" in cmdline + except Exception: + pass + # If we can't read cmdline, default to True (safer fallback) + return True + + +def stop() -> None: + if not os.path.isfile(PID_FILE): + print("ℹ No server appears to be running (no pidfile found).") + return + + try: + pid = int(open(PID_FILE).read().strip()) + except (ValueError, OSError): + print("⚠ Pidfile exists but is unreadable. Removing it.") + os.remove(PID_FILE) + return + + if not _is_running(pid): + print(f"ℹ Server (PID {pid}) is not running. Cleaning up pidfile.") + os.remove(PID_FILE) + return + + print(f"🛑 Stopping server (PID {pid}) …") + + # Graceful shutdown (SIGTERM) + os.kill(pid, signal.SIGTERM) + + # Wait up to 10 seconds for graceful exit + for i in range(20): + time.sleep(0.5) + if not _is_running(pid): + break + else: + # Force kill if still alive + print(f" ⚠ Server didn't stop gracefully, sending SIGKILL …") + os.kill(pid, signal.SIGKILL) + time.sleep(0.5) + + # Clean up pidfile + if os.path.isfile(PID_FILE): + os.remove(PID_FILE) + + if _is_running(pid): + print(f"❌ Failed to stop server (PID {pid}).") + sys.exit(1) + else: + print(f"✅ Server stopped.") + + +if __name__ == "__main__": + stop()