Skip to content

Video Remuxing vs Transcoding

A conversion finishes in about a second and the file barely changes size when the codec inside already fits the new container. It takes seconds to minutes and the size actually moves when it doesn't, because every frame gets decoded and built back up from scratch.

When a file won't open ยท Updated

We repackaged the same 1080p clip into MKV, MOV and AVI with FFmpeg's -c copy and each one finished in about 0.2 seconds, landing within half a percent of the source's 30.7 MB. Re-encoding that same clip to H.264 at a normal quality setting took 2.3 seconds and came out 76% smaller. Same source file, same target containers even in one case: a completely different operation happened underneath.

Why was your conversion instant, and why didn't the size change?

Because the video and audio inside your file were already a codec the new container can hold, so FileFlip copied the compressed data across instead of rebuilding it. That's a remux, and copying bytes cannot make them fewer.

  • You'll get a remux, near-instant and same-size, when you're only swapping the container and the codec inside already fits the target: H.264 or H.265 between MP4, MOV and MKV covers most of the traffic on convert MKV to MP4, MOV to MP4 and AVI to MP4.
  • You'll get a transcode, slower and a different size, the moment you change Resolution, Bitrate or Frame rate under Advanced options, or the codec inside doesn't fit the container you picked at all.
  • If you actually want the file smaller, a remux won't do it. See making a video file smaller for email for the control that does.

Remuxing vs transcoding at a glance

Remux Transcode
What happens to the video stream Copied byte for byte into the new container Decoded to raw frames, then re-encoded
Time, our 10-second 1080p clip 0.2 seconds 2.3 to 4.0 seconds
File size Same, within container overhead Whatever the bitrate or CRF you set produces
Quality Bit-identical on decode Some loss every pass, even at a matched bitrate
Happens when The codec inside already fits the target container The codec doesn't fit, or you changed resolution, bitrate or frame rate

What does a remux actually do?

It copies the already-compressed video stream into a new container's bookkeeping, untouched. Nothing about the picture is decoded, so nothing about it can change.

We took a 10-second, 1920x1080 H.264 clip at 30.7 MB and ran ffmpeg -i source.mp4 -c copy output.mkv, the same for MOV and AVI. Every one finished in under a quarter of a second:

Target Time Size Change
MKV 0.19s 30,703,320 bytes -0.004%
MOV 0.18s 30,704,465 bytes 0.00%
AVI 0.20s 30,849,980 bytes +0.47%

We then decoded every frame of the source and every remux and hashed each one with FFmpeg's -f framemd5. The MKV and MOV hashes matched the source exactly, all 300 frames, in order. That's not "close": it's the identical stream, because -c copy never touched it.

What does a transcode actually do?

It decodes every frame back to raw pixels, then runs the encoder again as if from a fresh source, spending real CPU time on every one.

We re-encoded the same clip to H.264 at CRF 23, a typical "keep it good" setting, and to H.265 at CRF 28, a smaller target that swaps the codec too:

Target Time Size Change
H.264, CRF 23 2.31s 7,464,001 bytes -75.7%
H.265, CRF 28 4.00s 3,193,370 bytes -89.6%

Both took 12 to 21 times longer than any of the remuxes above, on the machine we ran this on. That ratio is what scales: remuxing costs time in proportion to how many bytes are on disk, which a hard drive moves fast, while transcoding costs time in proportion to how many frames there are to decode and re-encode, which is real, per-pixel computation. A ten-minute clip won't take 0.2 seconds to remux, but it stays close to instant; a ten-minute transcode takes proportionally as long as our ten-second one did.

How do you predict which one you'll get?

Check whether the codec already inside your file is one the destination container is built to hold.

Container Codecs it can hold Coming from an H.264 or H.265 MP4
MP4 H.264, H.265, AV1 Already there
MOV Same box structure as MP4, plus ProRes, DV Remux
MKV Any codec at all, per the format's own Matroska specification, IETF RFC 9559 Remux
AVI MPEG-4 Part 2, Motion JPEG, older codecs Remux, usually, see below
WebM VP8, VP9 or AV1 only Always a transcode

MP4, MOV and MKV share enough codec support that moving between them is almost always a remux. WebM sits at the other end: it only allows VP8, VP9 or AV1, so an MP4 holding H.264 has to be re-encoded to get in at all, no matter what settings you pick.

MP4MKVMOVAVI
CompressionVaries by fileVaries by fileVaries by fileVaries by file
Embedded metadataYesYesYesYes
AudioYesYesYesYes
VideoYesYesYesYes
Subtitle tracksYesYesYesNo
ChaptersYesYesYesNo
StreamingYesYesYesNo
Released2001200219911992
DeveloperISO/IEC MPEG (Moving Picture Experts Group)Matroska (Steve Lhomme and contributors)AppleMicrosoft
Pulled from the same registry behind our format reference pages, so it can't drift out of step with them.

Why can't a remux make the file smaller?

Because nothing about how the picture is encoded changes. The bits describing each frame are the same bits, just moved into a different box.

File size after each operation on the same 30.7 MB clip
  • Remux to MKV30.7 MB, unchanged
  • Transcode, same bitrate29.9 MB
  • Transcode, CRF 237.5 MB
  • Transcode, HEVC CRF 283.2 MB

The remux and the bitrate-matched transcode land in almost the same place. Size tracks the settings you choose, not whether the container changed.

The small moves you do see, MKV -0.004%, AVI +0.47%, come from container bookkeeping: index tables, headers, padding, not from the picture. If you want the file smaller, remuxing was never going to do it. Making a video file smaller for email covers the Bitrate control that actually works, and by how much.

What does a transcode cost you in quality?

Some, even when you try to keep everything the same, because every decode-and-re-encode cycle requantizes the picture again.

We measured VMAF, scored against the untouched source, for each transcode above, plus a version re-encoded at the source's own 24.5 Mbps bitrate to isolate the cost of the round trip itself from the cost of a lower bitrate:

Transcode VMAF
Same bitrate (24.5 Mbps) 97.3
CRF 23 93.3
HEVC CRF 28 90.0

None of those is the ceiling. Comparing the untouched source against a plain copy of itself, the same VMAF tooling reports 99.9, not a perfect 100, which is measurement noise rather than a real difference. Even the bitrate-matched transcode gives up about 2.6 points against that ceiling for no size benefit at all, purely from being decoded and re-encoded once.

Same frame, before and after a 1 Mbps transcode
Transcoded to 1 Mbps H.264
Source, untouched
Source, untouchedTranscoded to 1 Mbps H.264

Both frames are the same instant in the clip. The right side was re-encoded at 1 Mbps, a real bitrate setting for shrinking a video, and scores VMAF 62.2 against the source over the whole clip. Magnified 2x from a 320 by 180 pixel crop.

Can a remux still go wrong?

Rarely, but AVI is the one to watch. Every frame we decoded from our AVI remux hashed identical to the source, so the picture itself came through untouched. What moved was the timestamps: FFmpeg renumbered every frame's position by a constant offset, because classic AVI has no separate field for a frame's decode order versus its display order the way MP4, MOV and MKV do, documented in FFmpeg's own bitstream filter reference under the filter written to work around it. On a file with an audio track, that's the kind of gap that shows up as drift between picture and sound, which is one more reason to treat AVI as the format you convert away from rather than into.

Common questions

Does transcoding always make the file smaller?

No. It depends entirely on the bitrate or quality setting you choose, not on the act of re-encoding itself. Our bitrate-matched transcode above landed within 2.8% of the source's size while still taking over three seconds and losing a measurable amount of quality, because re-encoding and shrinking are two separate decisions.

Will FileFlip ever transcode when I only wanted to change the container?

Yes, whenever the codec inside your file isn't one the target container can hold. Converting an H.264 MP4 to WebM is the clearest example: WebM only allows VP8, VP9 or AV1, so the video gets re-encoded no matter what settings you leave alone.

Does re-encoding lose quality even at the exact same bitrate?

Yes, measurably. Our bitrate-matched transcode above scored VMAF 97.3 against a 99.9 ceiling, giving up quality it didn't have to for zero size benefit. It's the same requantization cost covered in lossy vs lossless compression, just from one re-encode instead of twenty.

Can you convert a video with no quality loss at all?

Only through a remux: swap the container, leave Resolution, Bitrate and Frame rate alone, and pick a target the codec already fits. The moment any of those changes, or the codec doesn't fit, it's a transcode and some quality is gone for good.

Convert between them

FileFlip converts MKV, MOV and AVI to MP4 entirely in your browser, on the same FFmpeg build this post's numbers came from. Nothing uploads and there's no account; leave Resolution, Bitrate and Frame rate untouched under Advanced options if a remux is what you're after.

How we measured this

  • Source clip: the same 10-second, 1920x1080, 30 fps H.264 segment of Big Buck Bunny (Blender Foundation, CC BY 3.0) at roughly 24.5 Mbps used in making a video file smaller for email, fetched with pnpm blog:corpora.
  • Remux: ffmpeg -i source.mp4 -c copy output.<ext> for MKV, MOV and AVI, timed with /usr/bin/time -p.
  • Transcode: ffmpeg -i source.mp4 -c:v libx264 -crf 23 -preset medium output.mp4, the same with -c:v libx265 -crf 28 -tag:v hvc1, and a third run at -b:v 24.5M -maxrate 24.5M -bufsize 49M to hold bitrate constant while still forcing a full decode and re-encode.
  • Frame identity: ffmpeg -i file -f framemd5 on the source and each remux, comparing the hash and timestamp of every one of the 300 frames.
  • Quality: FFmpeg's libvmaf filter, candidate against the untouched source, both streams already at the same 1920x1080 resolution so no scaling was involved.
  • Tools: FFmpeg 8.1.2 with libx264, libx265 and libvmaf, on macOS.
  • Caveat: one 10-second clip is a single data point, and the exact seconds above are specific to the machine we ran them on; a longer or more detailed source will change the absolute numbers while keeping the same shape, because remux time tracks bytes and transcode time tracks frames.
  • Reproducing it: node scripts/benchmark-video-encoders.mjs <clip> in the repository prints the container and VMAF tables this post draws from; the CRF and matched-bitrate transcode timings were run directly against the same clip.