45

I have mp4 video of 1920x1080. I would like to crop the video to 480x270 without quality loss.

I am using the following command:

ffmpeg -i input.mp4 -filter:v "crop=480:270:200:200" -crf 23 output.mp4

I also tried:

ffmpeg -i input.mp4 -filter:v "crop=480:270:200:100" -c:a copy -qp 0 output.mp4

I used -crf 23 and -qp 0 for loseless video cropping, but after cropping video has lost quality.

Does anyone know how I can crop the video without losing the quality?

9
  • Please show the complete console output from your ffmpeg command.
    – llogan
    Commented Oct 28, 2015 at 5:50
  • here u can find the console output: dropbox.com/s/1r4pdgdmtj9ilnm/consol-output.rtf?dl=0 Thanks
    – mrana
    Commented Oct 28, 2015 at 13:04
  • You should edit your question to include the console output. You can crop during playback. Will that be an acceptable solution?
    – llogan
    Commented Oct 28, 2015 at 16:43
  • crop during the playback? what shell i add with this command for that?<br> ffmpeg -i input.mp4 -filter:v "crop=480:270:200:100" -c:a copy -qp 0 output.mp4
    – mrana
    Commented Oct 29, 2015 at 10:47
  • There is no lossless crop for H.264, you are re-encoding the content. Hence, the quality loss. Commented Oct 29, 2015 at 11:11

4 Answers 4

67

You can't perform any filtering without losing quality when encoding to a lossy format, but you have some options.

Crop with your player

A possible solution would be to crop during playback, so you don't even need to re-encode. It is also useful to preview a crop.

This method will not create an output file. This will use your video player to crop while it is playing. See one of the other methods below if you want an output file.

With ffplay and crop filter:

ffplay -vf "crop=480:270:200:100" input.mp4

With vlc (or cvlc):

vlc input.mp4 --crop=480x270+200+100

Or you could crop with the VLC GUI: Tools → Effects & Filters → Video Effects → Crop.

Accept some quality loss (you may not even notice a difference)

Give it enough bits and you may not be able to tell there is a quality difference:

ffmpeg -i input -vf "crop=480:270:200:100" -c:v libx264 -crf 17 -c:a copy ouput.mp4

See FFmpeg Wiki: H.264 Video Encoding Guide for more info.

Use a bitstream filter

The h264_metadata and hevc_metadata bitstream filters can set crop dimensions without modifying the video itself.

Note: Your player may not support this method.

Example for H.264 video:

ffmpeg -i input.mp4 -c copy -bsf:v h264_metadata=crop_left=100:crop_right=20:crop_top=10:crop_bottom=10 output.mp4
  • Sets the frame cropping offsets in the SPS. These values will replace the current ones if the stream is already cropped.

  • These fields are set in pixels. Note that some sizes may not be representable if the chroma is subsampled or the stream is interlaced (see H.264 section 7.4.2.1.1).

Use a lossless format

ffmpeg can encode with several lossless encoders: ffv1, huffyuv, ffvhuff, utvideo, libx264 (using -crf 0 or -qp 0). The output will be lossless but the output file will be huge.

Note: Your player may not support this method.

ffmpeg -i input.mp4 -vf "crop=480:270:200:100" -c:v ffv1 -c:a copy output.mkv

or

ffmpeg -i input.mp4 -vf "crop=480:270:200:100" -c:v libx264 -crf 0 -c:a copy output.mp4

If your input is MJPEG

Stream copy the individual images with ffmpeg, crop them losslessly with jpegtran, then remux them with ffmpeg. This will result in no loss, but you will be restricted to the ancient MJPEG format.

18
  • In my mac i have ffmpeg installed already, i am not sure how i can use ffplay?
    – mrana
    Commented Nov 3, 2015 at 14:43
  • I used Homebrew. as far i remember i followed these instructions: trac.ffmpeg.org/wiki/CompilationGuide/MacOSX Thanks
    – mrana
    Commented Nov 3, 2015 at 18:18
  • yes i know, but i always get ffplay not found message: Masuds-MacBook-Pro:golf masudrana$ cd selected Masuds-MacBook-Pro:selected masudrana$ ffplay -vf "crop=480:270:200:100" golf.mp4 -bash: ffplay: command not found
    – mrana
    Commented Nov 3, 2015 at 20:47
  • @MasudRana Maybe it didn't install or it is not in your PATH. I'm not familiar with OS X, so I can't recommend anything else. Try searching for the ffplay binary. Alternatively, get ffplay from evermeet.cx/ffmpeg.
    – llogan
    Commented Nov 3, 2015 at 20:53
  • 2
    Using bitstream filter worked perfectly when playing back the new video in mplayer, but would be messed up in both VLC (3.0.9.2) and Kodi (18). Commented Feb 28, 2021 at 11:33
6

For some video formats at least, the soft solution based on metadata should be possible with FFmpeg as well by using bitstream filters from libavcodec, e.g. hevc_metadata or h264_metadata.

Unlike filters like crop and cropdetect, this does not require decoding. The syntax slightly differs, though, because you can only set the amount of cropping from the four edges, not the target rectangle size. For the OP's 480×270 area at position (200,200) from the top left in a 1920×1080 full HD frame, we get:

  • ffmpeg -i input.mp4 -codec copy -bsf:v h264_metadata=crop_left=200:crop_right=1240:crop_top=200:crop_bottom=610 output.mp4

Since this is codec metadata, this should work regardless the container format, i.e. not just in MP4, but in MKV or AVI as well. Alas, I have not tested it myself yet and cannot say anything about support in software and hardware players. (A first simple check failed miserably, though.)

For more detailed info, FFmpeg's documentation refers to sections 7.4.3.2.1 and 7.4.2.1.1 of the H.265 and H.264 specifications respectively, which are freely available from ITU and are basically equivalent:

  • frame_cropping_flag equal to 1 specifies that the frame cropping offset parameters follow next in the sequence parameter set. frame_cropping_flag equal to 0 specifies that the frame cropping offset parameters are not present.
  • frame_crop_left_offset, frame_crop_right_offset, frame_crop_top_offset, frame_crop_bottom_offset specify the samples of the pictures in the coded video sequence that are output from the decoding process, in terms of a rectangular region specified in frame coordinates for output. The variables CropUnitX and CropUnitY are derived as follows:

    – If ChromaArrayType is equal to 0, CropUnitX and CropUnitY are derived as: CropUnitX = 1 CropUnitY = 2 − frame_mbs_only_flag – Otherwise (ChromaArrayType is equal to 1, 2, or 3), CropUnitX and CropUnitY are derived as: CropUnitX = SubWidthC CropUnitY = SubHeightC * ( 2 − frame_mbs_only_flag )

The frame cropping rectangle contains luma samples with horizontal frame coordinates from CropUnitX * frame_crop_left_offset to PicWidthInSamplesL − ( CropUnitX * frame_crop_right_offset + 1 ) and vertical frame coordinates from CropUnitY * frame_crop_top_offset to ( 16 * FrameHeightInMbs ) − ( CropUnitY * frame_crop_bottom_offset + 1 ), inclusive.

The value of frame_crop_left_offset shall be in the range of 0 to ( PicWidthInSamplesL / CropUnitX ) − ( frame_crop_right_offset + 1 ), inclusive; and the value of frame_crop_top_offset shall be in the range of 0 to ( 16 * FrameHeightInMbs / CropUnitY ) − ( frame_crop_bottom_offset + 1 ), inclusive.

When frame_cropping_flag is equal to 0, the values of frame_crop_left_offset, frame_crop_right_offset, frame_crop_top_offset, and frame_crop_bottom_offset shall be inferred to be equal to 0.

When ChromaArrayType is not equal to 0, the corresponding specified samples of the two chroma arrays are the samples having frame coordinates ( x / SubWidthC, y / SubHeightC ), where ( x, y ) are the frame coordinates of the specified luma samples.

For decoded fields, the specified samples of the decoded field are the samples that fall within the rectangle specified in frame coordinates.

2
  • 2
    This is a nice solution. It really doesn't reencode the h264 video. I tried this with one of my video files, but it didn't work reliably between different video players. I am using VLC Player and it interprets crop_left and crop_top wrong, the video has been cropped from the right and bottom instead. Then I tried Windows Media Player and there the same video was cropped as intended from top and left. I need to have the video cropped in all players the same way, so I cannot use this option.
    – MarekJ47
    Commented Feb 10, 2020 at 12:43
  • @MarekJ47 VLC is so very buggy, who cares. Commented Jun 23, 2023 at 6:19
3

At a basic level you cannot make use of a lossy encoding and then expect it to not lose quality when you decode and then encode again. The only way that works is to make use of a lossless codec, for example Quicktime with the Animation codec. This is just a basic truth of digital video production that you cannot work around by just passing command line options to ffmpeg.

6
  • there must be some way, coz i am not compressing the video but cropping it.
    – mrana
    Commented Oct 27, 2015 at 23:10
  • 3
    but you are compressing the video. Video can not be modified while in its compressed form. Just like any other compresses content, like a zip file. It must be uncompressed, modified (cropped), then compressed again. Thant being said, you shouldn't lose TOO much quality give an high enough bitrate.
    – szatmary
    Commented Oct 28, 2015 at 0:10
  • Masud, why did you ask a question if you were going to ignore the answer? For background information please see: howtogeek.com/142174/…
    – MoDJ
    Commented Oct 28, 2015 at 0:19
  • @MoDJ sorry i am new in stackoverflow
    – mrana
    Commented Oct 28, 2015 at 9:35
  • 3
    Note that this answer talks about "decode and then encode again". OP seems to not know that cropping requires de- and encoding. This is necessary because cropping changes the image data (if you want to drop the unused data).
    – Kissaki
    Commented May 30, 2016 at 10:53
3

This is not possible using ffmpeg.

As alternative you can embed your video in a Matroska (.mkv) container and set a cropping tag in the file header, but it must be supported by your player.

Reportedly, for H264-encoded videos H264info can also be used, but i still need to figure out how to use it...

1
  • 1
    This should also be possible with FFmpeg bitstream filters, see my answer (which started out as a comment to this one).
    – Crissov
    Commented Feb 6, 2020 at 10:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.