Comfy-Org/ComfyUI · error · ValueError

H.264 output requires even dimensions, got {out_width}x{out_

Error message

H.264 output requires even dimensions, got {out_width}x{out_height}

What it means

The H.264 encoder (libx264) requires even width and height because of 4:2:0 chroma subsampling. Before opening the output, the transcode path takes the first frame's dimensions (swapped if the stream carries 90/270-degree rotation metadata) and raises if either dimension is odd, rather than letting libx264 fail obscurely or silently cropping.

Source

Thrown at comfy_api/latest/_input_impl/video_types.py:658

                            video_done = True
                            if last_video_pts is not None:
                                # the source continues past the window: hold the last kept frame to the window end
                                end_offset = video_pts_offset if video_pts_offset is not None else start_pts
                                last_video_end = max(last_video_end, end_pts - end_offset)
                            break
                        # the source's true display duration of this frame; average_rate is not a
                        # frame duration (sparse/VFR sources), so it is only the fallback
                        frame_duration = frame.duration if frame.duration else pts_step
                        if end_pts is not None and frame.pts is not None:
                            frame_duration = min(frame_duration, end_pts - frame.pts)
                        if output is None:
                            rotation_k = int(round(frame.rotation // 90)) % 4 if frame.rotation else 0
                            if rotation_k % 2:
                                out_width, out_height = frame.height, frame.width
                            else:
                                out_width, out_height = frame.width, frame.height
                            if out_width % 2 or out_height % 2:
                                raise ValueError(f"H.264 output requires even dimensions, got {out_width}x{out_height}")
                            source_size = (frame.width, frame.height)
                            output = av.open(path, **open_kwargs)
                            # Add metadata before writing any streams
                            write_output_metadata(container, output, metadata)
                            out_video = output.add_stream("h264", rate=rate)
                            # no B-frames: reordering makes mp4 sample durations follow decode order,
                            # so irregular-VFR spans and trim windows land wrong
                            out_video.codec_context.max_b_frames = 0
                            out_video.width = out_width
                            out_video.height = out_height
                            out_video.pix_fmt = pix_fmt
                            if crf is not None:
                                out_video.options = {"crf": str(crf)}
                            # source pts pass through (rebased to 0), so variable frame rate survives
                            out_video.codec_context.time_base = video_stream.time_base
                            if audio_stream is not None:
                                out_audio = output.add_stream("aac", rate=sample_rate, layout=layout)
                        if (frame.width, frame.height) != source_size:

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Pre-crop/pad the source to even dimensions before loading (ffmpeg -vf crop=even dims or pad)
  2. Add a scale filter to even sizes: scale=trunc(iw/2)*2:trunc(ih/2)*2 in an external pass
  3. If the input is generated in ComfyUI, produce latent/image sizes divisible by 2 before saving

Example fix

// before
video_input.save_transcoded('out.mp4')  # source is 1081x1920

# after
# pre-process: ffmpeg -i in.mp4 -vf "crop=1080:1920:0:0" even.mp4
VideoFromFile('even.mp4').save_transcoded('out.mp4')
Defensive patterns

Strategy: validation

Validate before calling

w, h = video_input.get_size()
if w % 2 or h % 2:
    raise ValueError(f'crop/pad {w}x{h} to even dimensions before H.264 output')

Type guard

def has_even_dims(size) -> bool:
    return size[0] % 2 == 0 and size[1] % 2 == 0

Prevention

When it happens

Trigger: Transcoding a video whose first frame has an odd width or height (e.g. 1081x1920, 641x480) — including cases where a rotation flag swaps an odd dimension into the other axis.

Common situations: Odd-resolution phone screen recordings; AI-generated videos with non-multiple-of-2 sizes; crops from other tools that land on odd boundaries.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/dca7dab2bcaeb247. Report an issue: GitHub.