Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/cmake/testing.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ macro (oiio_add_all_tests)
ENABLEVAR ENABLE_FITS
IMAGEDIR fits-images
URL http://www.cv.nrao.edu/fits/data/tests/)
oiio_add_tests (ffmpeg
ENABLEVAR ENABLE_FFMPEG
FOUNDVAR FFmpeg_FOUND)
oiio_add_tests (gif
FOUNDVAR GIF_FOUND ENABLEVAR ENABLE_GIF
IMAGEDIR oiio-images/gif URL "Recent checkout of OpenImageIO-images")
Expand Down
3 changes: 3 additions & 0 deletions src/doc/builtinplugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,9 @@ Some special attributes are used for movie files:
* - ``ffmpeg:TimeCode``
- string
- Start time timecode
* - ``CICP``
- int[4]
- Coding-independent code points to describe the color profile.



Expand Down
12 changes: 9 additions & 3 deletions src/ffmpeg.imageio/ffmpeginput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,9 @@ ffmpeg_input_imageio_create()
// QuickTime / MOV
// raw MPEG-4 video
// MPEG-1 Systems / MPEG program stream
OIIO_EXPORT const char* ffmpeg_input_extensions[] = {
"avi", "mov", "qt", "mp4", "m4a", "3gp", "3g2", "mj2", "m4v", "mpg", nullptr
};
OIIO_EXPORT const char* ffmpeg_input_extensions[]
= { "avi", "mov", "qt", "mp4", "m4a", "3gp",
"3g2", "mj2", "m4v", "mpg", "mkv", nullptr };


OIIO_PLUGIN_EXPORTS_END
Expand Down Expand Up @@ -531,6 +531,12 @@ FFmpegInput::open(const std::string& name, ImageSpec& spec)
m_spec.attribute("oiio:BitsPerSample",
m_codec_context->bits_per_raw_sample);
m_spec.attribute("ffmpeg:codec_name", m_codec_context->codec->long_name);
/* The ffmpeg enums are documented to match CICP values, except the color range. */
const int cicp[4]
= { m_codec_context->color_primaries, m_codec_context->color_trc,
m_codec_context->colorspace,
m_codec_context->color_range == AVCOL_RANGE_MPEG ? 0 : 1 };
m_spec.attribute("CICP", TypeDesc(TypeDesc::INT, 4), cicp);
m_nsubimages = m_frames;
spec = m_spec;
m_filename = name;
Expand Down
87 changes: 87 additions & 0 deletions testsuite/ffmpeg/ref/out-ffmpeg-6.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
Reading ref/vp9_display_p3.mkv
ref/vp9_display_p3.mkv : 192 x 108, 3 channel, uint8 FFmpeg movie
7 subimages: 192x108 [u8,u8,u8]
subimage 0: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: E65FAFBDA14543571188F8A84F75E1567E13148C
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
Comment on lines +8 to +11
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Lack of an ffmpeg test has masked (until now) that we aren't translating some of the common items into the canonical OIIO names. "DATE" should be "DateTime". "SCENE" probably should be "ImageDescription"?

This is a longstanding issue, you don't need to fix it as part of this PR. But we should come back to it. In fact, I will add it as an issue that feels like an appropriate Dev Days sized task!

Copy link
Contributor Author

@brechtvl brechtvl Sep 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This movie file was written by Blender. I would rather expect something should be fixed on the Blender side to follow metadata naming conventions. The code for this is very old, and probably at the time was mainly intended to be consumed by Blender.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, maybe I misunderstood. If those are simply the names Blender chose, then we are reporting it accurately. I think I assumed that these were some kind of standard naming that ffmpeg imposes. Carry on.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to explain:

Lots of times, different image file formats use different metadata names for what are conceptually the same thing. Like, what the TIFF spec calls "ImageDescription" is obviously meant to be the same thing that the JPEG spec calls "Caption".

Since a design goal of OIIO is to allow format-agnostic reading, an application should be able to use the same API calls to read from many formats without needing to special case them (as much as possible), so the last thing an app wants to do is somehow know under what metadata name it will find the image description or the capture date, for each and every format it may encounter.

So for the intersection of the most useful and most common metadata items, we have a canonical name that OIIO uses and presents to the user, with each file format handler doing the name translation on the way in and out. Hence, they all translate the date and time data into the same string layout and call it "DateTime", etc.

But that only matters if it's something determined by the format itself. If this is just arbitrary name/value stuff that was put in by the app that wrote the file, we don't try to guess what it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that makes sense. It's indeed just arbitrary metadata.

I was just thinking it would be nice if Blender wrote metadata in such a way that it ends up as e.g. DateTime in OIIO, and then caries over better when converting to other file formats. But that's not OIIO's problem of course.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to add to the confusion, it's called "capTime" in OpenEXR. But OIIO knows how to translate metadata called "DateTime" into "capTime" when it's writing an exr file.

Yes, if you happen to name it DateTime, then if it's read by OIIO and written to other files, it will know that it's the canonical date/time field and will rename it appropriately for each format that has a different specified name for the obviously same meaning of the data.

ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 1: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 8D54A542C4E6A47A4F8829993001786BA62288DF
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 2: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 8D54A542C4E6A47A4F8829993001786BA62288DF
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 3: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 8D54A542C4E6A47A4F8829993001786BA62288DF
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 4: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: D9B0B8782048AEE24C4DF767E2B0969EBAB9D36B
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 5: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: C6B5666BB0A937A59762B8FE846BF50FED40889E
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 6: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 63516D95A1BB56E9E9483F9BCFC4305851A8BC54
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
87 changes: 87 additions & 0 deletions testsuite/ffmpeg/ref/out-ffmpeg8.0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
Reading ref/vp9_display_p3.mkv
ref/vp9_display_p3.mkv : 192 x 108, 3 channel, uint8 FFmpeg movie
7 subimages: 192x108 [u8,u8,u8]
subimage 0: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: C882152FF48CB068931C2710175659A9D0493C08
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 1: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 1E2EB62F7BDD2DAC5C6FBDE582EE19978DC7C290
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 2: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 1E2EB62F7BDD2DAC5C6FBDE582EE19978DC7C290
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 3: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 1E2EB62F7BDD2DAC5C6FBDE582EE19978DC7C290
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 4: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 35565DB895AB1CA413192B7F25A1890718CFC0F5
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 5: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 338C9A82B74CE3B291DAD6564AE7C060AE6D9267
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
subimage 6: 192 x 108, 3 channel, uint8 FFmpeg movie
SHA-1: 90BC91EAA745A9C897EEDEC0D34BAAF1D40B1C7C
channel list: R, G, B
CICP: 12, 1, 1, 1
DATE: "2025/09/13 21:58:33"
ENCODER: "Lavf61.7.100"
FramesPerSecond: 24/1 (24)
SCENE: "Scene"
ffmpeg:codec_name: "Google VP9"
oiio:BitsPerSample: 0
oiio:Movie: 1
oiio:subimages: 7
Binary file added testsuite/ffmpeg/ref/vp9_display_p3.mkv
Binary file not shown.
10 changes: 10 additions & 0 deletions testsuite/ffmpeg/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env python

# Copyright Contributors to the OpenImageIO project.
# SPDX-License-Identifier: Apache-2.0
# https://github.com/AcademySoftwareFoundation/OpenImageIO

imagedir = "ref/"
files = [ "vp9_display_p3.mkv" ]
for f in files:
command = command + info_command (os.path.join(imagedir, f))
Loading