Video sequencer does not recognize pixel format 'yuvj420p' correctly #44827

Closed
opened 2015-05-24 17:28:03 +02:00 by Mikael Hakansson · 15 comments

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.

**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.

Changed status to: 'Open'

Changed status to: 'Open'

Added subscriber: @DrPepper

Added subscriber: @DrPepper

Added subscriber: @mont29

Added subscriber: @mont29
Sergey Sharybin was assigned by Bastien Montagne 2015-05-24 17:55:05 +02:00

This sounds like FFMpeg issue, Sergey?

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

This sounds like FFMpeg issue, Sergey? @DrPepper: we for sure need an (as small as possible!) video clip demonstrating the issue.

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)

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.

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).

gopro_yuv420p_bt709.mp4

gopro_yuv420p_after_blender_render.mov

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). [gopro_yuv420p_bt709.mp4](https://archive.blender.org/developer/F179614/gopro_yuv420p_bt709.mp4) [gopro_yuv420p_after_blender_render.mov](https://archive.blender.org/developer/F179615/gopro_yuv420p_after_blender_render.mov)

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!

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!

Added subscriber: @Psy-Fi

Added subscriber: @Psy-Fi

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.

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

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
Member

Added subscriber: @Blendify

Added subscriber: @Blendify

Changed status from 'Open' to: 'Archived'

Changed status from 'Open' to: 'Archived'

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.

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.

Added subscriber: @satishgoda1

Added subscriber: @satishgoda1
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
6 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#44827
No description provided.