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.birkb...@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.birkb...@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.birkb...@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".