{"record":{"id":"10e7db788f2b5c94","repo":"invoke-ai/InvokeAI","slug":"input-videos-are-width-x-height-h-264-encoding","errorCode":null,"errorMessage":"Input videos are {width}x{height}; H.264 encoding requires even dimensions. Re-encode or crop the sources to even width and height first.","messagePattern":"Input videos are (.+?)x(.+?); H\\.264 encoding requires even dimensions\\. Re-encode or crop the sources to even width and height first\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/video_concat.py","lineNumber":134,"sourceCode":"    def invoke(self, context: InvocationContext) -> VideoOutput:\n        if len(self.videos) < 2:\n            raise ValueError(\"video_concat requires at least two input videos.\")\n\n        paths: list[Path] = [context.videos.get_path(v.video_name) for v in self.videos]\n\n        # Probe inputs up front: enforce matching dims and pick the default output fps.\n        probes = [probe_video(p) for p in paths]\n        widths = {(w, h) for (w, h, _, _) in probes}\n        if len(widths) > 1:\n            raise ValueError(\n                f\"All inputs must share the same dimensions. Got: \"\n                f\"{sorted(widths)}. Re-render at a single resolution before concatenating.\"\n            )\n        width, height, _, _first_fps = probes[0]\n        # libx264 + yuv420p needs even dimensions; we encode with macro_block_size=1 to\n        # preserve the source dimensions exactly, so reject odd sources with a clear error.\n        if width % 2 or height % 2:\n            raise ValueError(\n                f\"Input videos are {width}x{height}; H.264 encoding requires even dimensions. \"\n                \"Re-encode or crop the sources to even width and height first.\"\n            )\n        self._validate_transition_memory(width, height)\n        output_fps = self._resolve_output_fps([probe[3] for probe in probes])\n\n        context.util.signal_progress(f\"Joining {len(self.videos)} clip(s) ({self.transition}) @ {output_fps:.2f} fps\")\n\n        tmp = tempfile.NamedTemporaryFile(prefix=\"invokeai_video_concat_\", suffix=\".mp4\", delete=False)\n        tmp.close()\n        tmp_path = Path(tmp.name)\n        try:\n            # Frames stream from the decoders straight into the encoder; only the\n            # transition windows are buffered. See _iter_joined_frames.\n            writer = make_mp4_writer(tmp_path, output_fps)\n            num_frames = 0\n            try:\n                clip_iters = [iter_video_frames(p, is_canceled=context.util.is_canceled) for p in paths]","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/video_concat.py#L116-L152","documentation":"H.264 (libx264 + yuv420p) requires even width and height. video_concat keeps source dimensions exactly (macro_block_size=1), so it rejects odd-dimension inputs up front with a descriptive ValueError instead of silently resizing.","triggerScenarios":"Concatenating videos whose width or height is odd, e.g. 853x480 or 1920x1081.","commonSituations":"Cropped screen recordings with odd crop sizes; legacy footage at odd dimensions; images-to-video pipelines producing 1-pixel-off sizes.","solutions":["Re-encode or crop sources so both width and height are even (e.g. crop 853x480 to 852x480)","Apply a crop/scale node in the workflow before video_concat","Use ffmpeg: -vf \"crop=trunc(iw/2)*2:trunc(ih/2)*2\" to make dimensions even"],"exampleFix":"// before\nvideos=[clip_853x480]\n// after\n# pre-process: ffmpeg -i in.mp4 -vf crop=trunc(iw/2)*2:trunc(ih/2)*2 even.mp4\nvideos=[clip_852x480]","handlingStrategy":"validation","validationCode":"w, h = probe_video(path)[:2]\nif w % 2 or h % 2:\n    raise ValueError(f\"{path} is {w}x{h}; crop/scale to even dimensions before concat\")","typeGuard":"def has_even_dimensions(w: int, h: int) -> bool:\n    return w % 2 == 0 and h % 2 == 0","tryCatchPattern":"try:\n    output = concat.invoke(context)\nexcept ValueError as e:\n    if \"requires even dimensions\" in str(e):\n        videos = [reencode_even(v) for v in videos]  # ffmpeg crop=trunc(iw/2)*2:trunc(ih/2)*2\n        output = concat.invoke(context)\n    else:\n        raise","preventionTips":["After cropping, round crop sizes down to even numbers","Prefer scales like 1920x1080/1280x720; avoid 1-pixel-off exports","Add a pre-flight ffprobe check for odd dimensions in automation scripts"],"tags":["video","encoding","h264"],"backgroundTag":"odd-video-dimensions","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}