I would like to resize a 4K mkv video to 1920×1080 with ffmpeg version 3.4.6-0ubuntu0.18.04.1 on Ubuntu 18.04. The original file has the following features:

Input #0, matroska,webm
encoder         : libebml v1.3.9 + libmatroska v1.5.2
Stream #0:0(eng): Video: hevc (Main 10), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 3840x2160 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 23.98 tbc (default)

This version of FFmpeg may not support x265. I compiled a new version from the current Git repository, explicitly enabling x265. Now, ffmpeg -hide_banner -pix_fmts has, in its output:

IO... yuv420p10le            3            15

This format should now be supported both for encoding and for decoding. I tried:

ffmpeg -i original_file.mkv -c:v libx265 -pix_fmt + -vf scale=1920:1080 -colorspace bt709 -c:a copy test_output.mkv

This produces:

Input #0, matroska,webm, from 'test_output.mkv':
    ENCODER         : Lavf58.35.100
    Stream #0:0(eng): Video: hevc (Main 10), yuv420p10le(tv, bt709/unknown/unknown), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 23.98 tbc (default)

So, it is apparently ok. However, test_output.mkv colors still seem to be half the intensity of the original one, as if a grey layer was overlapped to the 4K video. I opened the file with both vlc and mpv, with no difference.

  1. How to preserve the original colors as much as possible?

  2. If it is possible, I would also like to lower the bitrate, but my attempt

    ffmpeg -i original_file.mkv -s 1920x1080 -b 1700 output.mkv

    produced a solid grey-only video with some moving squares.

I always get this message:

[matroska,webm @ 0x55a5507ad100] Could not find codec parameters for stream 1 (Subtitle: hdmv_pgs_subtitle (pgssub)): unspecified size
Consider increasing the value for the 'analyzeduration' and 'probesize' options

FFmpeg built from source has the following configuration:

ffmpeg version N-95768-gd831edc387 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
configuration: --enable-gpl --enable-libx264 --enable-libx265
libavutil      56. 36.100 / 56. 36.100
libavcodec     58. 62.100 / 58. 62.100
libavformat    58. 35.100 / 58. 35.100
libavdevice    58.  9.101 / 58.  9.101
libavfilter     7. 66.100 /  7. 66.100
libswscale      5.  6.100 /  5.  6.100
libswresample   3.  6.100 /  3.  6.100
libpostproc    55.  6.100 / 55.  6.100

Ad 1:

Try adding the -pix_fmt yuv420p10le option (e.g. before -vf). Or only -pix_fmt + for using the same pixel format as the input video has.

If it doesn't help, you obviously have an inappropriate, albeit more common FFmpeg version — only for 8-bit colors. (Your original video uses 10-bit colors, and FFmpeg will try use the best 8-bit pixel format in this case — with the colors' degradation, of course.)

FFmpeg may be built for 8-bit colors or for 10-bit colors, or — in recent time — for both of them (for your HEVC encoded video).

So you need to build (or obtain by other way) version for 8-/10- or 10-bit color depth.

Ad 2:

Bitrate of 1700 is very low — only 1700 bits per second, i. e. about 212 bytes per second.

To reach such a low bitrate and at the same time reach your 23.98 frames per second, the encoder is limited with average size for 1 frame about 212 / 24 = 9 bytes only!

Did you see a picture of such small memory? It has almost no information, so the gray image.

You probably wanted 1700k (Kilobits per second) — or, more probably — 170k:

-b:v 170k

so correct your command in this way.

Addendum to Ad 1:

You use the (default) 4:2:0 chroma subsampling (with inevitable color and contrast degradation).
Try the maximum quality, i.e. 4:4:4 (no subsampling), or — if it will be sufficient for you — 4:2:2.

To reach this, use -pix_fmt yuv444p10le and change the video profile to main444-10 (with option -profile:v main444-10).

  • Thank you for all the very useful explanations. I tried with a compiled-from-source (with x265 enabled) version of FFmpeg and also with a packaged newer version. Even using (in both cases) -pix_fmt yuv420p10le, the problem is the same. Check out the error message I added in the question, if it is useful. Moreover, FFmpeg creates an x264 output by default; how to preserve the original HEVC instead? – BowPark Nov 18 '19 at 11:11
  • Use ffmpeg -hide_banner -pix_fmts to see if you have yuv420p10le pixel format in your build. If not, you build doesn't support 10-bit color depth. Add -c:v libx265 to your commands for obtaining HEVC output. The error message appended into your question has nothing with your problems. – MarianD Nov 18 '19 at 16:00
  • 1
    Your input has a set of non-standard color parameters (bt2020nc/bt2020/smpte2084). Use the colorspace filter to convert to standard bt709. Color range is not relevant here, and low bitrates will degrade image color, but not the primary factor in this case. – Gyan Nov 19 '19 at 15:13
  • 1
    The colorspace filter, not the option. – Gyan Nov 19 '19 at 16:19
  • 1
    I'll attend to this tomorrow. – Gyan Nov 19 '19 at 17:04

There is already a solution here. But I will try to summarize it in brief.

You need to specify the correct flags for color properties of the original file. Your original file (as probably many other files) has these properties: yuv420p10le(tv, bt2020nc/bt2020/smpte2084). So you need to add the following arguments respectively: -pix_fmt, -color_range, -colorspace, -color_primaries, and -color_trc. The last four are just flags (those in parenteses), so if you encoded the file already, you do not need to do it again, just add the correct flags. Your arguments then should look like this:

-c:v libx265
-pix_fmt +
-color_range tv 
-colorspace bt2020nc
-color_primaries bt2020 
-color_trc smpte2084  
-vf scale=1920:1080

As mentioned elsewhere, the color format property -pix_fmt with value + means "use the same pixel format", but you can specify it manually: -pix_fmt yuv420p10le.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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