Page MenuHome

Video sequencer does not recognize pixel format 'yuvj420p' correctly
Closed, ArchivedPublic

Description

System Information
Linux Mint 17.1, Nvidia GTX 580

Blender Version
Broken: 2.74

Short description of error
When using the video sequencer, I discovered that Blender does not seem to handle the pixel format yuvj420p correctly. This results in incorrect color reproduction and output.
As you might know, the pixel format yuv420p (without the 'j') stores the color values between values 16 (black) and 239 (white), while the format yuvj420p utilizes the whole range between 0 and 255. Currently, it seems that Blender incorrectly identifies, or treats, the yuvj420p format as if it was a yuv420p format, thus distorting the colors.

I think this issue matters to many, since yuvj420p is what the GoPro camera delivers, and likely many other consumer digital cameras.

Exact steps for others to reproduce the error
In the video editing environment, import an unmodified GoPro (I have the Hero 4 Black) movie clip with Add->Movie. If you compare the blender output or preview, you will see that the colors look different than if the same movie clip is played back with any video player, such as vlc. It seems to be most obvious in bright, saturated areas.

GoPro movie clips can be sent upon request. If one does not have access to yuvj420p files, another way to expose the error would be to convert an existing yuv420p file to yuvj420p with ffmpeg, and then bring it in to blender, and compare with the original file.
ffmpeg -i INPUT_FILE -acodec copy -vcodec libx264 -pix_fmt:v yuvj420p OUTPUT_FILE.mp4

To check the pixel format an existing movie clip, use ffprobe.

Event Timeline

Mikael Hakansson (DrPepper) raised the priority of this task from to 90.
Mikael Hakansson (DrPepper) updated the task description. (Show Details)
Mikael Hakansson (DrPepper) edited a custom field.

This sounds like FFMpeg issue, Sergey?

@Mikael Hakansson (DrPepper): we for sure need an (as small as possible!) video clip demonstrating the issue.

Bastien Montagne (mont29) lowered the priority of this task from 90 to 30.May 24 2015, 5:55 PM

I will try to find a representative video clip, which is not too long.

However, I made some new discoveries. If I use ffmpeg and transcode from yuvj420p (straight from GoPro) to yuvj420p again, blender interprets the transcoded file correctly! The difference, when investigating with ffprobe is:
GoPro file: Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709)
Transcoded file: Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc)

The only difference is the bt709 descriptor to the yuvj420p pixel format. It seems as if Blender does not know what to do with this flag(?), because when it goes away, Blender interprets the file correctly. I have no idea what bt709 means though, and it is not described in ffmpeg.

(Although a transcode is a workaround, it is not desirable as you will always lose some image quality)

Ok, did some more investigation. It seems as if it is not the 'j' in yuvj420p which is the problem, but instead the bt709 flag/parameter.

I put a native GoPro clip through Lightworks rendering engine (interprets file correctly), and the result has the pixel format: yuv420p(tv, bt709). This rendered clip gets distorted colors when I import it in Blender (but nowhere else). The common denominator here is the bt709, and not the 'j' as I first thought.

Here are two video files illustrating the problem. Description of files:

gopro_yuv420p_bt709.mp4 - Has the pixel format "yuv420p(tv, bt709)". Works (interprets colors correctly) with all video players I have tried, and works with Lightworks. However, Blender does not reproduce the colors correctly for this file.

gopro_yuv420p_after_blender_render.mov - This is what the video clip above looks like, after being put through Blender. Most notably, the reds have become orange. The file now simply has the pixel format yuv420p. If you import the first (bt709) file into Blender, and render it out, this is what I expect you will get. Upon reimporting this file into Blender, the result will not change, presumably since the bt709 flag is no longer present.

So, just to reiterate, the issue is no longer the yuvj420p format, but rather the bt709 flag (which can be on both yuv420p and yuvj420p).

I have looked further into what this bt709 is, and it turns out to be a color matrix. I don't fully understand how they are applied, but I assume it is a form of lookup table. With ffmpeg you can convert between different color matrices by using the colormatrix filter. I can recreate the effect of putting a bt709 file through blender with:

ffmpeg -i gopro_yuv420p_bt709.mp4 -vf colormatrix=bt709:bt601 wrong_colors.mp4

The file wrong_colors.mp4 will now look identical to the attached gopro_yuv420p_after_blender_render.mov
Conversely, I can convert the output from blender (with wrong colors) to the right colorspace with:

ffmpeg -i gopro_yuv420p_after_blender_render.mov -vf colormatrix=bt601:bt709 correct_colors.mp4

I hope this helps in understanding how to implement the correct color treatment in Blender!

The problematic line is:

inv_table = sws_getCoefficients(anim->pCodecCtx->colorspace);

in anim_movie.c

either commenting it or using

table = sws_getCoefficients(anim->pCodecCtx->colorspace);

solves it.

I looked briefly at the docs for ffmpeg and it looks like these lines should be correct after all? (inv_table should be the input colorspace). I tried using an RGB colorspace for table but this breaks as well. The issue might also be elsewhere, such as doing double colorspace conversion somewhere or so but I don't have time to investigate more

Aaron Carlisle (Blendify) raised the priority of this task from 30 to Normal.May 28 2015, 12:07 AM
Sergey Sharybin (sergey) changed the task status from Unknown Status to Unknown Status.Jul 13 2015, 5:15 PM

I'm not really convinced it is a blender bug. First of all, code indeed seems correct here. Second of all, the result in blender matches behavior of mplayer, vlc and ffplay. it might be something wrong in ffmpeg library itself, but it is to be reported to ffmpeg community.

So thanks for the report, but don't think we can help much here.