[FFmpeg-devel] [PATCH] libavutil: add clean aperture (CLAP) side data.
Neil Birkbeck
neil.birkbeck at gmail.com
Mon Apr 27 07:27:53 EEST 2020
The clean aperature represents a cropping of the stored image data used to
relate the image data to a canonical video system and exists as container
metadata (see 'clap' section in https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html)
Addition of the side data is a first step towards demuxing CLAP atom metadata,
helping to resolve https://trac.ffmpeg.org/ticket/7437
This CleanAperture representation can also carry PixelCrop fields from MKV.
Side data was suggested as a way to carry such PixelCrop fields in:
https://ffmpeg.org/pipermail/ffmpeg-devel/2016-March/192302.html
Transmuxing the side data can then be added (MOV to/from MKV), and
auto-application could optionally be enabled like autorotate in ffmpeg_filter.c.
Signed-off-by: Neil Birkbeck <neil.birkbeck at gmail.com>
---
libavcodec/avpacket.c | 1 +
libavcodec/packet.h | 12 ++++++++
libavformat/dump.c | 15 +++++++++
libavutil/Makefile | 2 ++
libavutil/clean_aperture.c | 30 ++++++++++++++++++
libavutil/clean_aperture.h | 63 ++++++++++++++++++++++++++++++++++++++
6 files changed, 123 insertions(+)
create mode 100644 libavutil/clean_aperture.c
create mode 100644 libavutil/clean_aperture.h
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 55b509108e..2ff779720b 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -397,6 +397,7 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type)
case AV_PKT_DATA_AFD: return "Active Format Description data";
case AV_PKT_DATA_ICC_PROFILE: return "ICC Profile";
case AV_PKT_DATA_DOVI_CONF: return "DOVI configuration record";
+ case AV_PKT_DATA_CLEAN_APERTURE: return "Clean Aperture";
}
return NULL;
}
diff --git a/libavcodec/packet.h b/libavcodec/packet.h
index 41485f4527..a0f8c29a33 100644
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -282,6 +282,18 @@ enum AVPacketSideDataType {
*/
AV_PKT_DATA_DOVI_CONF,
+ /**
+ * This side data contains a crop region (clean aperture) that defines the
+ * region of the stored image that should be cropped.
+ *
+ * It is intended to be used to store crop-related metadata from the
+ * container. For example, the CLAP atom in MOV files, and PixelCrop fields
+ * in MKV.
+ *
+ * The data is of type AVCleanAperture (see libavutil/clean_aperture.h)
+ */
+ AV_PKT_DATA_CLEAN_APERTURE,
+
/**
* The number of side data types.
* This is not part of the public API/ABI in the sense that it may
diff --git a/libavformat/dump.c b/libavformat/dump.c
index 5e9a03185f..060e7b2d10 100644
--- a/libavformat/dump.c
+++ b/libavformat/dump.c
@@ -26,6 +26,7 @@
#include "libavutil/display.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
+#include "libavutil/clean_aperture.h"
#include "libavutil/mastering_display_metadata.h"
#include "libavutil/dovi_meta.h"
#include "libavutil/mathematics.h"
@@ -402,6 +403,16 @@ static void dump_dovi_conf(void *ctx, AVPacketSideData* sd)
dovi->dv_bl_signal_compatibility_id);
}
+static void dump_clean_aperture(void *ctx, AVPacketSideData *sd)
+{
+ AVCleanAperture *clap = (AVCleanAperture *)sd->data;
+ av_log(ctx, AV_LOG_INFO, "[width %d/%d height:%d/%d h_offset:%d/%d v_offset:%d/%d]",
+ clap->width.num, clap->width.den,
+ clap->height.num, clap->height.den,
+ clap->horizontal_offset.num, clap->horizontal_offset.den,
+ clap->vertical_offset.num, clap->vertical_offset.den);
+}
+
static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
{
int i;
@@ -468,6 +479,10 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
av_log(ctx, AV_LOG_INFO, "DOVI configuration record: ");
dump_dovi_conf(ctx, &sd);
break;
+ case AV_PKT_DATA_CLEAN_APERTURE:
+ av_log(ctx, AV_LOG_INFO, "Clean aperture:");
+ dump_clean_aperture(ctx, &sd);
+ break;
default:
av_log(ctx, AV_LOG_INFO,
"unknown side data type %d (%d bytes)", sd.type, sd.size);
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 966eec41aa..e9c9b2bff1 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -17,6 +17,7 @@ HEADERS = adler32.h \
cast5.h \
camellia.h \
channel_layout.h \
+ clean_aperture.h \
common.h \
cpu.h \
crc.h \
@@ -107,6 +108,7 @@ OBJS = adler32.o \
cast5.o \
camellia.o \
channel_layout.o \
+ clean_aperture.o \
color_utils.o \
cpu.o \
crc.o \
diff --git a/libavutil/clean_aperture.c b/libavutil/clean_aperture.c
new file mode 100644
index 0000000000..0be51725f3
--- /dev/null
+++ b/libavutil/clean_aperture.c
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2020 Neil Birkbeck <neil.birkbeck at gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include "clean_aperture.h"
+#include "mem.h"
+
+AVCleanAperture *av_clean_aperture_alloc(void)
+{
+ return av_mallocz(sizeof(AVCleanAperture));
+}
diff --git a/libavutil/clean_aperture.h b/libavutil/clean_aperture.h
new file mode 100644
index 0000000000..116cf36976
--- /dev/null
+++ b/libavutil/clean_aperture.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2020 Neil Birkbeck <neil.birkbeck at gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_CLEAN_APERTURE_H
+#define AVUTIL_CLEAN_APERTURE_H
+
+#include "frame.h"
+#include "rational.h"
+
+
+/**
+ * Clean aperture represents the subset of stored pixels (as width, height
+ * and a center offset) that relates the pixels of the stored image to a
+ * canonical display area.
+ *
+ * The clean aperture structure is meant to be allocated as stream side data.
+ * It represents the Clean Aperture Atom (CLAP) and container-level cropping
+ * information (e.g., PixelCrop fields in MKV).
+ *
+ * @note The struct should be allocated with av_clean_aperture_alloc()
+ * and its size is not a part of the public ABI.
+ */
+typedef struct AVCleanAperture {
+ // The width of the aperture window (<= stored image width)
+ AVRational width;
+
+ // The height of the aperture window (<= stored image height)
+ AVRational height;
+
+ // The horizontal offset of the center (relative to stored image center)
+ AVRational horizontal_offset;
+
+ // The vertical offset of the center (relative to stored image center)
+ AVRational vertical_offset;
+} AVCleanAperture;
+
+/**
+ * Allocate an AVCleanAperture structure and set its fields to
+ * default values. The resulting struct can be freed using av_freep().
+ *
+ * @return An AVCleanAperture filled with default values or NULL
+ * on failure.
+ */
+AVCleanAperture *av_clean_aperture_alloc(void);
+
+#endif /* AVUTIL_CLEAN_APERTURE_H */
--
2.26.2.303.gf8c07b1a785-goog
More information about the ffmpeg-devel
mailing list