[FFmpeg-devel] [PATCH v3 1/5] avformat/matroskadec: Parse Block Additional Mapping elements
Most of the implementation was done by the Plex developers. Signed-off-by: quietvoid --- libavformat/matroska.h| 7 +++ libavformat/matroskadec.c | 44 +-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..4b2a3310a4 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 500c83ac3a..74c3fbc2a4 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -239,6 +239,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +276,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +427,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +578,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_OF(matroska_track) }; +static EbmlSyntax matroska_block_addition_mapping[] = { +{ MATROSKA_ID_BLKADDIDVALUE, EBML_UINT, 0, 0, offsetof(MatroskaBlockAdditionMapping, value) }, +{ MATROSKA_ID_BLKADDIDNAME, EBML_STR, 0, 0, offsetof(MatroskaBlockAdditionMapping, name) }, +{ MATROSKA_ID_BLKADDIDTYPE, EBML_UINT, 0, 0, offsetof(MatroskaBlockAdditionMapping, type) }, +{ MATROSKA_ID_BLKADDIDEXTRADATA, EBML_BIN, 0, 0, offsetof(MatroskaBlockAdditionMapping, extradata) }, +CHILD_OF(matroska_track) +}; + static EbmlSyntax matroska_track[] = { { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, 0, offsetof(MatroskaTrack, num) }, { MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, 0, offsetof(MatroskaTrack, name) }, @@ -593,6 +609,7 @@ static EbmlSyntax matroska_track[] = { { MATROSKA_ID_TRACKOPERATION,EBML_NEST, 0, 0, offsetof(MatroskaTrack, operation),{ .n = matroska_track_operation } }, { MATROSKA_ID_TRACKCONTENTENCODINGS, EBML_NEST, 0, 0, 0, { .n = matroska_track_encodings } }, { MATROSKA_ID_TRACKMAXBLKADDID, EBML_UINT, 0, 0, offsetof(MatroskaTrack, max_block_additional_id), { .u = 0 } }, +{ MATROSKA_ID_TRACKBLKADDMAPPING,EBML_NEST, 0, sizeof(MatroskaBlockAdditionMapping), offsetof(MatroskaTrack, block_addition_mappings), { .n = matroska_block_addition_mapping } }, { MATROSKA_ID_SEEKPREROLL, EBML_UINT, 0, 0, offsetof(MatroskaTrack, seek_preroll), { .u = 0 } }, { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE }, { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE }, @@ -2306,6 +2323,25 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track, return 0; } +static int mkv_parse_block_addition_mappings(AVFormatContext *s, AVStream *st, const MatroskaTrack *track) +{ +const EbmlList *mappings_list = &track->block_addition_mappings; +MatroskaBlockAdditionMapping *mappings = mappings_lis
[FFmpeg-devel] [PATCH v3 2/5] avformat/matroskadec: Parse dvcC/dvvC block additional mapping
The parsing was implemented in a new dovi_isom file for the unification of the mov/mpegts DOVI parsing into one function, in a following patch. Most of the Matroska elements implementation was done by Plex developers. Signed-off-by: quietvoid --- libavformat/Makefile | 2 +- libavformat/dovi_isom.c | 80 +++ libavformat/dovi_isom.h | 29 ++ libavformat/matroskadec.c | 15 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/Makefile b/libavformat/Makefile index c45caa3eed..61a1fecf6c 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -313,7 +313,7 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..2c0a49c993 --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,80 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id +); + +return 0; +} diff --git a/libavformat/dovi_isom.h b/libavformat/dovi_isom.h new file mode 100644 index 00..4c313046a7 --- /dev/null +++ b/libavformat/dovi_isom.h @@ -0,0 +1,29 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * 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 + * vers
[FFmpeg-devel] [PATCH v3 3/5] avformat/matroskaenc: Write dvcC/dvvC block additional mapping
When muxing to Matroska, write the Block Additional Mapping if there is AV_PKT_DATA_DOVI_CONF side data present. Most of the code was implemented by Plex developers. Since the type (dvcC/dvvC) can change depending on the caller, the logic was separated from ff_isom_put_dvcc_dvvc. In this case, movenc uses MKTAG while matroskaenc uses MKBETAG. This would allow refactoring movenc in the future. Signed-off-by: quietvoid --- libavformat/Makefile | 2 +- libavformat/dovi_isom.c | 40 libavformat/dovi_isom.h | 6 ++ libavformat/matroskaenc.c | 43 +++ 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index 61a1fecf6c..680030014d 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -317,7 +317,7 @@ OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c index 2c0a49c993..747ffc8b2c 100644 --- a/libavformat/dovi_isom.c +++ b/libavformat/dovi_isom.c @@ -21,6 +21,8 @@ #include "libavutil/dovi_meta.h" +#include "libavcodec/put_bits.h" + #include "avformat.h" #include "dovi_isom.h" @@ -78,3 +80,41 @@ int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf return 0; } + +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], uint64_t size, + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; +init_put_bits(&pb, out, size); + +if (size < ISOM_DVCC_DVVC_SIZE) +return AVERROR(EINVAL); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_profile > 7 ? "dvvC" : "dvcC", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id); + +return put_bytes_output(&pb); +} diff --git a/libavformat/dovi_isom.h b/libavformat/dovi_isom.h index 4c313046a7..8ff59ef495 100644 --- a/libavformat/dovi_isom.h +++ b/libavformat/dovi_isom.h @@ -22,8 +22,14 @@ #ifndef AVFORMAT_DOVI_ISOM_H #define AVFORMAT_DOVI_ISOM_H +#include "libavutil/dovi_meta.h" + #include "avformat.h" +#define ISOM_DVCC_DVVC_SIZE 24 + int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size); +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], uint64_t size, + AVDOVIDecoderConfigurationRecord *dovi); #endif /* AVFORMAT_DOVI_ISOM_H */ diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 039f20988a..067474d8ed 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -54,6 +54,8 @@ #include "libavcodec/xiph.h" #include "libavcodec/mpeg4audio.h" +#include "libavformat/dovi_isom.h" + /* Level 1 elements we create a SeekHead entry for: * Info, Tracks, Chapters, Attachments, Tags (potentially twice) and Cues */ #define MAX_SEEKHEAD_ENTRIES 7 @@ -1115,6 +1117,41 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, return 0; } +static int mkv_write_dovi(AVFormatContext *s, AVIOContext *pb, AVStream *st) +{ +int ret; +AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *) +
[FFmpeg-devel] [PATCH v3 4/5] avformat/mov: Refactor DOVI box parsing to use ff_isom_parse_dvcc_dvvc
Read at most 24 bytes, but in reality only 5 bytes are used for parsing. The rest of the bytes are reserved in the specification. Signed-off-by: quietvoid --- libavformat/mov.c | 51 ++- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index bbb45864df..6667d551b8 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -61,6 +61,8 @@ #include "mov_chan.h" #include "replaygain.h" +#include "libavformat/dovi_isom.h" + #if CONFIG_ZLIB #include #endif @@ -6799,58 +6801,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > ISOM_DVCC_DVVC_SIZE) { +read_size = ISOM_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ffio_read_size(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); +read_size = ret; -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static const MOVParseTableEntry mov_default_parse_table[] = { -- 2.33.0 ___ 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".
[FFmpeg-devel] [PATCH v3 5/5] avformat/mpegts: Refactor DOVI descriptor parsing to use ff_isom_parse_dvcc_dvvc
Also fixes incorrect parsing of dv_bl_signal_compatibility_id, which was often set to zero instead of the actual value, for mpegts only. Signed-off-by: quietvoid --- libavformat/mpegts.c | 44 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index da8eee2414..75ef59d186 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -39,6 +39,9 @@ #include "avio_internal.h" #include "mpeg.h" #include "isom.h" + +#include "libavformat/dovi_isom.h" + #if CONFIG_ICONV #include #endif @@ -2162,49 +2165,10 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type break; case 0xb0: /* DOVI video stream descriptor */ { -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; int ret; -if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + 1) / 8 -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); -dovi->dv_version_major = get8(pp, desc_end); -dovi->dv_version_minor = get8(pp, desc_end); -buf = get16(pp, desc_end); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (desc_end - *pp >= 20) { // 4 + 4 * 4 -buf = get8(pp, desc_end); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; -} - -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ff_isom_parse_dvcc_dvvc(fc, st, *pp, desc_len)) < 0) return ret; -} - -av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); } break; default: -- 2.33.0 ___ 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".
Re: [FFmpeg-devel] [PATCH v3 2/5] avformat/matroskadec: Parse dvcC/dvvC block additional mapping
On 26/09/2021 07.13, myp...@gmail.com wrote: On Sat, Sep 25, 2021 at 11:58 PM quietvoid wrote: The parsing was implemented in a new dovi_isom file for the unification of the mov/mpegts DOVI parsing into one function, in a following patch. Most of the Matroska elements implementation was done by Plex developers. Signed-off-by: quietvoid --- libavformat/Makefile | 2 +- libavformat/dovi_isom.c | 80 +++ libavformat/dovi_isom.h | 29 ++ libavformat/matroskadec.c | 15 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/Makefile b/libavformat/Makefile index c45caa3eed..61a1fecf6c 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -313,7 +313,7 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..2c0a49c993 --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,80 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id +); + +return 0; +} diff --git a/libavformat/dovi_isom.h b/libavformat/dovi_isom.h new file mode 100644 index 00..4c313046a7 --- /dev/null +++ b/libavformat/dovi_isom.h @@ -0,0 +1,29 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it
[FFmpeg-devel] [PATCH v4 1/4] avformat/dovi_isom Implement Dolby Vision configuration parsing/writing
According to specification "Dolby Vision Stream Within the ISO Base Media File Format Version 2.2" This only adds support for the "Dolby Vision configuration box". Other configuration boxes such as "Dolby Vision enhancement layer configuration box" are not supported. The new functions will be used to implement parsing/writing the DOVI config for Matroska. As well as to refactor MOV/MPEG TS to parse the DOVI box/descriptor using dovi_isom. Signed-off-by: quietvoid --- libavformat/dovi_isom.c | 120 libavformat/dovi_isom.h | 35 2 files changed, 155 insertions(+) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..747ffc8b2c --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,120 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "libavcodec/put_bits.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id +); + +return 0; +} + +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], uint64_t size, + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; +init_put_bits(&pb, out, size); + +if (size < ISOM_DVCC_DVVC_SIZE) +return AVERROR(EINVAL); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " +
[FFmpeg-devel] [PATCH v4 2/4] avformat/matroska{dec, enc} Parse BlockAdditionMapping elements
Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data for the video track. The configuration block is written when muxing into MKV if DOVI side data is present for the track. In version 2.2 of the Dolby ISOM specification, there is also dvwC but it is not in the Matroska spec. Most of the Matroska element parsing was implemented by Plex developers. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 7 + libavformat/matroskadec.c | 59 +-- libavformat/matroskaenc.c | 45 + 4 files changed, 111 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index c45caa3eed..680030014d 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -313,11 +313,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..4b2a3310a4 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 500c83ac3a..a50851b8d3 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -51,6 +51,8 @@ #include "libavcodec/mpeg4audio.h" #include "libavcodec/packet_internal.h" +#include "libavformat/dovi_isom.h" + #include "avformat.h" #include "avio_internal.h" #include "internal.h" @@ -239,6 +241,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +278,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +429,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +580,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_OF(matroska_track) }; +static EbmlSyntax matroska_block_addition_mapping[] = { +{ MATROSKA_ID_BLKADDIDVALUE, EB
[FFmpeg-devel] [PATCH v4 3/4] avformat/mov: Refactor DOVI box parsing to use ff_isom_parse_dvcc_dvvc
Read at most 24 bytes, but in reality only 5 bytes are used for parsing. The rest of the bytes are reserved in the specification. Signed-off-by: quietvoid --- libavformat/mov.c | 51 ++- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index d0b8b2595b..e052f7ad96 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -61,6 +61,8 @@ #include "mov_chan.h" #include "replaygain.h" +#include "libavformat/dovi_isom.h" + #if CONFIG_ZLIB #include #endif @@ -6799,58 +6801,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > ISOM_DVCC_DVVC_SIZE) { +read_size = ISOM_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ffio_read_size(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); +read_size = ret; -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static const MOVParseTableEntry mov_default_parse_table[] = { -- 2.33.0 ___ 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".
[FFmpeg-devel] [PATCH v4 4/4] avformat/mpegts: Refactor DOVI descriptor parsing to use ff_isom_parse_dvcc_dvvc
Also fixes incorrect parsing of dv_bl_signal_compatibility_id, which was often set to zero instead of the actual value, for mpegts only. Signed-off-by: quietvoid --- libavformat/mpegts.c | 44 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index da8eee2414..75ef59d186 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -39,6 +39,9 @@ #include "avio_internal.h" #include "mpeg.h" #include "isom.h" + +#include "libavformat/dovi_isom.h" + #if CONFIG_ICONV #include #endif @@ -2162,49 +2165,10 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type break; case 0xb0: /* DOVI video stream descriptor */ { -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; int ret; -if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + 1) / 8 -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); -dovi->dv_version_major = get8(pp, desc_end); -dovi->dv_version_minor = get8(pp, desc_end); -buf = get16(pp, desc_end); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (desc_end - *pp >= 20) { // 4 + 4 * 4 -buf = get8(pp, desc_end); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; -} - -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ff_isom_parse_dvcc_dvvc(fc, st, *pp, desc_len)) < 0) return ret; -} - -av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); } break; default: -- 2.33.0 ___ 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".
Re: [FFmpeg-devel] [PATCH v4 2/4] avformat/matroska{dec, enc} Parse BlockAdditionMapping elements
quietvoid: Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data for the video track. The configuration block is written when muxing into MKV if DOVI side data is present for the track. In version 2.2 of the Dolby ISOM specification, there is also dvwC but it is not in the Matroska spec. Most of the Matroska element parsing was implemented by Plex developers. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 7 + libavformat/matroskadec.c | 59 +-- libavformat/matroskaenc.c | 45 + 4 files changed, 111 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index c45caa3eed..680030014d 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -313,11 +313,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..4b2a3310a4 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 500c83ac3a..a50851b8d3 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -51,6 +51,8 @@ #include "libavcodec/mpeg4audio.h" #include "libavcodec/packet_internal.h" +#include "libavformat/dovi_isom.h" We use relative paths for headers in the same directory; and this inclusion should be added to the headers below, keeping its alphabetical ordering. This goes for lots of headers added by you. Had not realized the headers below were relative. Thanks. + #include "avformat.h" #include "avio_internal.h" #include "internal.h" @@ -239,6 +241,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +278,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +429,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matrosk
[FFmpeg-devel] [PATCH v5 1/4] avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing
According to specification "Dolby Vision Stream Within the ISO Base Media File Format Version 2.2" This only adds support for the "Dolby Vision configuration box". Other configuration boxes such as "Dolby Vision enhancement layer configuration box" are not supported. The new functions will be used to implement parsing/writing the DOVI config for Matroska. As well as to refactor MOV/MPEG TS to parse the DOVI box/descriptor using dovi_isom. Signed-off-by: quietvoid --- libavformat/dovi_isom.c | 120 libavformat/dovi_isom.h | 35 2 files changed, 155 insertions(+) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..747ffc8b2c --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,120 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "libavcodec/put_bits.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id +); + +return 0; +} + +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], uint64_t size, + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; +init_put_bits(&pb, out, size); + +if (size < ISOM_DVCC_DVVC_SIZE) +return AVERROR(EINVAL); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " +
[FFmpeg-devel] [PATCH v5 2/4] avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements
Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data for the video track. The configuration block is written when muxing into MKV if DOVI side data is present for the track. In version 2.2 of the Dolby ISOM specification, there is also dvwC but it is not in the Matroska spec. Most of the Matroska element parsing was implemented by Plex developers. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 9 ++ libavformat/matroskadec.c | 58 +-- libavformat/matroskaenc.c | 45 ++ 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index c45caa3eed..680030014d 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -313,11 +313,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..16491aae22 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB @@ -385,4 +392,6 @@ extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_P int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); +#define DVCC_DVVC_BLOCK_TYPE_NAME "Dolby Vision configuration" + #endif /* AVFORMAT_MATROSKA_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 500c83ac3a..afd9ce46d1 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -53,6 +53,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "internal.h" #include "isom.h" #include "matroska.h" @@ -239,6 +240,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +277,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +428,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8]
[FFmpeg-devel] [PATCH v5 4/4] avformat/mpegts: Refactor DOVI descriptor parsing to use ff_isom_parse_dvcc_dvvc
Also fixes incorrect parsing of dv_bl_signal_compatibility_id, which was often set to zero instead of the actual value, for mpegts only. Signed-off-by: quietvoid --- libavformat/mpegts.c | 43 +++ 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index da8eee2414..276864be93 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -37,8 +37,10 @@ #include "mpegts.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "mpeg.h" #include "isom.h" + #if CONFIG_ICONV #include #endif @@ -2162,49 +2164,10 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type break; case 0xb0: /* DOVI video stream descriptor */ { -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; int ret; -if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + 1) / 8 -return AVERROR_INVALIDDATA; -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = get8(pp, desc_end); -dovi->dv_version_minor = get8(pp, desc_end); -buf = get16(pp, desc_end); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (desc_end - *pp >= 20) { // 4 + 4 * 4 -buf = get8(pp, desc_end); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; -} - -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ff_isom_parse_dvcc_dvvc(fc, st, *pp, desc_len)) < 0) return ret; -} - -av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); } break; default: -- 2.33.0 ___ 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".
[FFmpeg-devel] [PATCH v5 3/4] avformat/mov: Refactor DOVI box parsing to use ff_isom_parse_dvcc_dvvc
Read at most 24 bytes, but in reality only 5 bytes are used for parsing. The rest of the bytes are reserved in the specification. Signed-off-by: quietvoid --- libavformat/mov.c | 50 +-- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index d0b8b2595b..f30a7145e6 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -54,6 +54,7 @@ #include "avformat.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "isom.h" #include "libavcodec/get_bits.h" @@ -6799,58 +6800,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > ISOM_DVCC_DVVC_SIZE) { +read_size = ISOM_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = avio_read(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); +read_size = ret; -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static const MOVParseTableEntry mov_default_parse_table[] = { -- 2.33.0 ___ 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".
Re: [FFmpeg-devel] [PATCH v5 4/4] avformat/mpegts: Refactor DOVI descriptor parsing to use ff_isom_parse_dvcc_dvvc
On 27/09/2021 19.16, quietvoid wrote: Also fixes incorrect parsing of dv_bl_signal_compatibility_id, which was often set to zero instead of the actual value, for mpegts only. Signed-off-by: quietvoid --- libavformat/mpegts.c | 43 +++ 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index da8eee2414..276864be93 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -37,8 +37,10 @@ #include "mpegts.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "mpeg.h" #include "isom.h" + #if CONFIG_ICONV #include #endif @@ -2162,49 +2164,10 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type break; case 0xb0: /* DOVI video stream descriptor */ { -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; int ret; -if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + 1) / 8 -return AVERROR_INVALIDDATA; -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = get8(pp, desc_end); -dovi->dv_version_minor = get8(pp, desc_end); -buf = get16(pp, desc_end); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (desc_end - *pp >= 20) { // 4 + 4 * 4 -buf = get8(pp, desc_end); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; -} - -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ff_isom_parse_dvcc_dvvc(fc, st, *pp, desc_len)) < 0) return ret; -} - -av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); } break; default: This patch is wrong for MPEG TS. According to the Dolby specification, there is a dependency_pid before dv_bl_signal_compatibility_id in the descriptor. Current parsing behaviour in master is also incorrect. However, I'm unsure if ff_isom_parse_dvcc_dvvc should support this, since this case is actually not for ISOM. ___ 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".
[FFmpeg-devel] [PATCH v6 1/4] avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing
According to specification "Dolby Vision Stream Within the ISO Base Media File Format Version 2.2" This only adds support for the "Dolby Vision configuration box". Other configuration boxes, such as "Dolby Vision enhancement layer configuration box" are not supported. The new functions will be used to implement parsing/writing the DOVI config for Matroska, as well as to refactor MOV/MPEG TS to parse the DOVI box/descriptor using dovi_isom. Signed-off-by: quietvoid --- libavformat/dovi_isom.c | 133 libavformat/dovi_isom.h | 36 +++ 2 files changed, 169 insertions(+) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..4f204d3dec --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,133 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "libavcodec/put_bits.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size, +int has_dependency_pid) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; +int min_compat_size; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// For MPEG2 TS +if (has_dependency_pid && !dovi->bl_present_flag) { +// dependency_pid 13 bits + reserved 3 bits +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +min_compat_size = 7; +} else { +min_compat_size = 5; +} + +// Has enough remaining data +if (size >= min_compat_size) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id +); + +return 0; +} + +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], uint64_t size, + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; +init_put_bits(&pb, out, size); + +if (size < ISOM_DVCC_DVVC_SIZE) +return AVERROR(EINVAL); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_c
[FFmpeg-devel] [PATCH v6 2/4] avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements
Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data. The configuration block is written when muxing into Matroska, if DOVI side data is present for the track. In version 2.2 of the Dolby ISOM specification, there is also dvwC but it is not in the Matroska spec. Most of the Matroska element parsing was implemented by Plex developers. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 9 ++ libavformat/matroskadec.c | 58 +-- libavformat/matroskaenc.c | 45 ++ 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index c45caa3eed..680030014d 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -313,11 +313,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..16491aae22 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB @@ -385,4 +392,6 @@ extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_P int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); +#define DVCC_DVVC_BLOCK_TYPE_NAME "Dolby Vision configuration" + #endif /* AVFORMAT_MATROSKA_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 500c83ac3a..96818bf295 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -53,6 +53,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "internal.h" #include "isom.h" #include "matroska.h" @@ -239,6 +240,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +277,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +428,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8]
[FFmpeg-devel] [PATCH v6 3/4] avformat/mov: Refactor DOVI box parsing to use ff_isom_parse_dvcc_dvvc
Read at most 24 bytes, but in reality only 5 bytes are used for parsing. The rest of the bytes are reserved in the specification. Signed-off-by: quietvoid --- libavformat/mov.c | 50 +-- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index d0b8b2595b..71294b5e19 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -54,6 +54,7 @@ #include "avformat.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "isom.h" #include "libavcodec/get_bits.h" @@ -6799,58 +6800,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > ISOM_DVCC_DVVC_SIZE) { +read_size = ISOM_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = avio_read(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); +read_size = ret; -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size, 0); } static const MOVParseTableEntry mov_default_parse_table[] = { -- 2.33.0 ___ 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".
[FFmpeg-devel] [PATCH v6 4/4] avformat/mpegts: Refactor DOVI descriptor parsing to use ff_isom_parse_dvcc_dvvc
Also fixes incorrect parsing of dv_bl_signal_compatibility_id, with correct skipping of dependency_pid in DOVI TS descriptor. Signed-off-by: quietvoid --- libavformat/mpegts.c | 43 +++ 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index da8eee2414..0d46a26c89 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -37,8 +37,10 @@ #include "mpegts.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "mpeg.h" #include "isom.h" + #if CONFIG_ICONV #include #endif @@ -2162,49 +2164,10 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type break; case 0xb0: /* DOVI video stream descriptor */ { -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; int ret; -if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + 1) / 8 -return AVERROR_INVALIDDATA; -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = get8(pp, desc_end); -dovi->dv_version_minor = get8(pp, desc_end); -buf = get16(pp, desc_end); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (desc_end - *pp >= 20) { // 4 + 4 * 4 -buf = get8(pp, desc_end); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; -} - -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ff_isom_parse_dvcc_dvvc(fc, st, *pp, desc_len, 1)) < 0) return ret; -} - -av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); } break; default: -- 2.33.0 ___ 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".
Re: [FFmpeg-devel] [PATCH 7/8] avformat/mpegts: Fix for the DOVI video stream descriptor
On Thu, Oct 14, 2021 at 9:36 AM wrote: > On Thu, Oct 14, 2021 at 09:18:16AM -0400, f tcChlisop0 wrote: > > On Thu, Oct 14, 2021 at 9:10 AM wrote: > > > > > From: Limin Wang > > > > > > By < v1.2>> > > > > > > Signed-off-by: Limin Wang > > > --- > > > libavformat/mpegts.c | 11 +-- > > > 1 file changed, 9 insertions(+), 2 deletions(-) > > > > > > diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c > > > index 44d9298..774964d 100644 > > > --- a/libavformat/mpegts.c > > > +++ b/libavformat/mpegts.c > > > @@ -2178,6 +2178,8 @@ int ff_parse_mpeg2_descriptor(AVFormatContext > *fc, > > > AVStream *st, int stream_type > > > AVDOVIDecoderConfigurationRecord *dovi; > > > size_t dovi_size; > > > int ret; > > > +int dependency_pid; > > > + > > > if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + 1) / 8 > > > return AVERROR_INVALIDDATA; > > > > > > @@ -2193,7 +2195,11 @@ int ff_parse_mpeg2_descriptor(AVFormatContext > *fc, > > > AVStream *st, int stream_type > > > dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit > > > dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit > > > dovi->bl_present_flag = buf & 0x01;// 1 bit > > > -if (desc_end - *pp >= 20) { // 4 + 4 * 4 > > > +if (!dovi->bl_present_flag && desc_end - *pp >= 2) { > > > +buf = get16(pp, desc_end); > > > +dependency_pid = buf >> 3; // 13 bits > > > +} > > > +if (desc_end - *pp >= 1) { // 8 bits > > > buf = get8(pp, desc_end); > > > dovi->dv_bl_signal_compatibility_id = (buf >> 4) & > 0x0f; > > > // 4 bits > > > } else { > > > @@ -2210,12 +2216,13 @@ int ff_parse_mpeg2_descriptor(AVFormatContext > *fc, > > > AVStream *st, int stream_type > > > } > > > > > > av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: > %d, > > > level: %d, " > > > - "rpu flag: %d, el flag: %d, bl flag: %d, > compatibility > > > id: %d\n", > > > + "rpu flag: %d, el flag: %d, bl flag: %d, > > > dependency_pid: %d, compatibility id: %d\n", > > > dovi->dv_version_major, dovi->dv_version_minor, > > > dovi->dv_profile, dovi->dv_level, > > > dovi->rpu_present_flag, > > > dovi->el_present_flag, > > > dovi->bl_present_flag, > > > + dependency_pid, > > > dovi->dv_bl_signal_compatibility_id); > > > } > > > break; > > > -- > > > 1.8.3.1 > > > > > > ___ > > > 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". > > > > > > > Hi, this is something I had fixed in this patchset: > > https://ffmpeg.org/pipermail/ffmpeg-devel/2021-September/286234.html > > However the dependency_pid is ignored, as it has no use presently. > > > > Which patch should take precedence? > > Sorry, I have noticed your patch before. By the quick review of your patch, > it's a lot function change and difficult to merge I think. I prefer to > fix the issue with existing code first instead of mixed function change. > Okay, that makes sense. I will wait and rebase before resending for review then. However I'm worried my patch will still result in ignoring dependency_pid, because it is not part of AVDOVIDecoderConfigurationRecord, unless it is added. > > > thanks, quietvoid > > ___ > > 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". > > -- > Thanks, > Limin Wang > ___ > 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". > ___ 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".
Re: [FFmpeg-devel] [PATCH 7/8] avformat/mpegts: Fix for the DOVI video stream descriptor
On Thu, Oct 14, 2021 at 9:52 AM wrote: > On Thu, Oct 14, 2021 at 09:45:45AM -0400, quietvoid wrote: > > On Thu, Oct 14, 2021 at 9:36 AM wrote: > > > > > On Thu, Oct 14, 2021 at 09:18:16AM -0400, f tcChlisop0 wrote: > > > > On Thu, Oct 14, 2021 at 9:10 AM wrote: > > > > > > > > > From: Limin Wang > > > > > > > > > > By < > > v1.2>> > > > > > > > > > > Signed-off-by: Limin Wang > > > > > --- > > > > > libavformat/mpegts.c | 11 +-- > > > > > 1 file changed, 9 insertions(+), 2 deletions(-) > > > > > > > > > > diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c > > > > > index 44d9298..774964d 100644 > > > > > --- a/libavformat/mpegts.c > > > > > +++ b/libavformat/mpegts.c > > > > > @@ -2178,6 +2178,8 @@ int ff_parse_mpeg2_descriptor(AVFormatContext > > > *fc, > > > > > AVStream *st, int stream_type > > > > > AVDOVIDecoderConfigurationRecord *dovi; > > > > > size_t dovi_size; > > > > > int ret; > > > > > +int dependency_pid; > > > > > + > > > > > if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + > 1) / 8 > > > > > return AVERROR_INVALIDDATA; > > > > > > > > > > @@ -2193,7 +2195,11 @@ int > ff_parse_mpeg2_descriptor(AVFormatContext > > > *fc, > > > > > AVStream *st, int stream_type > > > > > dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 > bit > > > > > dovi->el_present_flag = (buf >> 1) & 0x01;// 1 > bit > > > > > dovi->bl_present_flag = buf & 0x01;// 1 > bit > > > > > -if (desc_end - *pp >= 20) { // 4 + 4 * 4 > > > > > +if (!dovi->bl_present_flag && desc_end - *pp >= 2) { > > > > > +buf = get16(pp, desc_end); > > > > > +dependency_pid = buf >> 3; // 13 bits > > > > > +} > > > > > +if (desc_end - *pp >= 1) { // 8 bits > > > > > buf = get8(pp, desc_end); > > > > > dovi->dv_bl_signal_compatibility_id = (buf >> 4) & > > > 0x0f; > > > > > // 4 bits > > > > > } else { > > > > > @@ -2210,12 +2216,13 @@ int > ff_parse_mpeg2_descriptor(AVFormatContext > > > *fc, > > > > > AVStream *st, int stream_type > > > > > } > > > > > > > > > > av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, > profile: > > > %d, > > > > > level: %d, " > > > > > - "rpu flag: %d, el flag: %d, bl flag: %d, > > > compatibility > > > > > id: %d\n", > > > > > + "rpu flag: %d, el flag: %d, bl flag: %d, > > > > > dependency_pid: %d, compatibility id: %d\n", > > > > > dovi->dv_version_major, dovi->dv_version_minor, > > > > > dovi->dv_profile, dovi->dv_level, > > > > > dovi->rpu_present_flag, > > > > > dovi->el_present_flag, > > > > > dovi->bl_present_flag, > > > > > + dependency_pid, > > > > > dovi->dv_bl_signal_compatibility_id); > > > > > } > > > > > break; > > > > > -- > > > > > 1.8.3.1 > > > > > > > > > > ___ > > > > > 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". > > > > > > > > > > > > > Hi, this is something I had fixed in this patchset: > > > > https://ffmpeg.org/pipermail/ffmpeg-devel/2021-September/286234.html > > > > However the dependency_pid is ignored, as it has no use pre
Re: [FFmpeg-devel] [PATCH 7/8] avformat/mpegts: Fix for the DOVI video stream descriptor
On Wed, Oct 27, 2021 at 10:26 AM wrote: > On Wed, Oct 27, 2021 at 11:50:04AM +0300, Jan Ekström wrote: > > On Thu, Oct 14, 2021 at 5:31 PM wrote: > > > > > > On Thu, Oct 14, 2021 at 10:12:05AM -0400, quietvoid wrote: > > > > On Thu, Oct 14, 2021 at 9:52 AM wrote: > > > > > > > > > On Thu, Oct 14, 2021 at 09:45:45AM -0400, quietvoid wrote: > > > > > > On Thu, Oct 14, 2021 at 9:36 AM wrote: > > > > > > > > > > > > > On Thu, Oct 14, 2021 at 09:18:16AM -0400, f tcChlisop0 wrote: > > > > > > > > On Thu, Oct 14, 2021 at 9:10 AM > wrote: > > > > > > > > > > > > > > > > > From: Limin Wang > > > > > > > > > > > > > > > > > > By < Stream Format > > > > > > > v1.2>> > > > > > > > > > > > > > > > > > > Signed-off-by: Limin Wang > > > > > > > > > --- > > > > > > > > > libavformat/mpegts.c | 11 +-- > > > > > > > > > 1 file changed, 9 insertions(+), 2 deletions(-) > > > > > > > > > > > > > > > > > > diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c > > > > > > > > > index 44d9298..774964d 100644 > > > > > > > > > --- a/libavformat/mpegts.c > > > > > > > > > +++ b/libavformat/mpegts.c > > > > > > > > > @@ -2178,6 +2178,8 @@ int > ff_parse_mpeg2_descriptor(AVFormatContext > > > > > > > *fc, > > > > > > > > > AVStream *st, int stream_type > > > > > > > > > AVDOVIDecoderConfigurationRecord *dovi; > > > > > > > > > size_t dovi_size; > > > > > > > > > int ret; > > > > > > > > > +int dependency_pid; > > > > > > > > > + > > > > > > > > > if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 > + 1 + > > > > > 1) / 8 > > > > > > > > > return AVERROR_INVALIDDATA; > > > > > > > > > > > > > > > > > > @@ -2193,7 +2195,11 @@ int > > > > > ff_parse_mpeg2_descriptor(AVFormatContext > > > > > > > *fc, > > > > > > > > > AVStream *st, int stream_type > > > > > > > > > dovi->rpu_present_flag = (buf >> 2) & 0x01; > // 1 > > > > > bit > > > > > > > > > dovi->el_present_flag = (buf >> 1) & 0x01; > // 1 > > > > > bit > > > > > > > > > dovi->bl_present_flag = buf & 0x01; > // 1 > > > > > bit > > > > > > > > > -if (desc_end - *pp >= 20) { // 4 + 4 * 4 > > > > > > > > > +if (!dovi->bl_present_flag && desc_end - *pp > >= 2) { > > > > > > > > > +buf = get16(pp, desc_end); > > > > > > > > > +dependency_pid = buf >> 3; // 13 bits > > > > > > > > > +} > > > > > > > > > +if (desc_end - *pp >= 1) { // 8 bits > > > > > > > > > buf = get8(pp, desc_end); > > > > > > > > > dovi->dv_bl_signal_compatibility_id = > (buf >> 4) & > > > > > > > 0x0f; > > > > > > > > > // 4 bits > > > > > > > > > } else { > > > > > > > > > @@ -2210,12 +2216,13 @@ int > > > > > ff_parse_mpeg2_descriptor(AVFormatContext > > > > > > > *fc, > > > > > > > > > AVStream *st, int stream_type > > > > > > > > > } > > > > > > > > > > > > > > > > > > av_log(fc, AV_LOG_TRACE, "DOVI, version: > %d.%d, > > > > > profile: > > > > > > > %d, > > > > > > > > > level: %d, " > > > > > > > > > - "rpu flag: %d, el flag: %d, bl flag: > %d, > > > > > > &g
[FFmpeg-devel] [PATCH v7 0/4] Add support for Matroska BlockAdditionMapping elements
This patch set adds support for reading/writing the Matroska BlockAdditionMapping elements, as well as for reading/writing dvcC/dvvC blocks in Matroska. Created utility functions to read/write Dolby Vision boxes for ISOM. This was done to avoid duplicating the code, as the Matroska blocks and MOV boxes follow the same specification, defined by Dolby. Refactored the reading/writing in mov/movenc to use the new dovi_isom functions. Differences compared to v6: - Dropped the avformat/mpegts patch as suggested, because the specification is different from the ISOM specification defined by Dolby. - Added a patch to refactor avformat/movenc to further reduce the duplicated code. The implementation in dovi_isom is the same. - Moved init_put_bits after the size validation in ff_isom_put_dvcc_dvvc. - Added dvwC to the ff_isom_put_dvcc_dvvc logging. quietvoid (4): avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc libavformat/Makefile | 4 +- libavformat/dovi_isom.c | 121 ++ libavformat/dovi_isom.h | 35 +++ libavformat/matroska.h| 9 +++ libavformat/matroskadec.c | 58 +- libavformat/matroskaenc.c | 45 ++ libavformat/mov.c | 50 +++- libavformat/movenc.c | 26 +++- 8 files changed, 286 insertions(+), 62 deletions(-) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h -- 2.33.1 ___ 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".
[FFmpeg-devel] [PATCH v7 1/4] avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing
Both parse/write implementations are based on mov/movenc. This only adds support for the "Dolby Vision configuration box". Other configuration boxes, such as "Dolby Vision enhancement layer configuration box" are not supported. The new functions will be used to implement parsing/writing the DOVI config for Matroska, as well as to refactor both mov/movenc to use dovi_isom functions. Signed-off-by: quietvoid --- libavformat/dovi_isom.c | 121 libavformat/dovi_isom.h | 35 2 files changed, 156 insertions(+) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..54f17c90a5 --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,121 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "libavcodec/put_bits.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id); + +return 0; +} + +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], uint64_t size, + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; + +if (size < ISOM_DVCC_DVVC_SIZE) +return AVERROR(EINVAL); + +init_put_bits(&pb, out, size); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ + +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatib
[FFmpeg-devel] [PATCH v7 2/4] avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements
Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data. The configuration block is written when muxing into Matroska, if DOVI side data is present for the track. Most of the Matroska element parsing is based on Plex's FFmpeg source code. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 9 ++ libavformat/matroskadec.c | 58 +-- libavformat/matroskaenc.c | 45 ++ 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index 3d6c8ef8f5..f70db4551c 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -314,11 +314,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..16491aae22 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB @@ -385,4 +392,6 @@ extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_P int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); +#define DVCC_DVVC_BLOCK_TYPE_NAME "Dolby Vision configuration" + #endif /* AVFORMAT_MATROSKA_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index b2c4927e43..9e922c70f1 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -53,6 +53,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "internal.h" #include "isom.h" #include "matroska.h" @@ -239,6 +240,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +277,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +428,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +579,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_
[FFmpeg-devel] [PATCH v7 3/4] avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc
To avoid duplicating code. The implementation in dovi_isom is identical. Signed-off-by: quietvoid --- libavformat/mov.c | 50 +-- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 3fcb1dc908..5c393e45ad 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -55,6 +55,7 @@ #include "avformat.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "isom.h" #include "libavcodec/get_bits.h" @@ -7033,58 +7034,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > ISOM_DVCC_DVVC_SIZE) { +read_size = ISOM_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = avio_read(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); +read_size = ret; -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom) -- 2.33.1 ___ 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".
[FFmpeg-devel] [PATCH v7 4/4] avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc
Improves code legibility by not using bit shifts. Also avoids duplicating the dvcC/dvvC ISOM box writing code. Signed-off-by: quietvoid --- libavformat/movenc.c | 26 +- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 37d4403f7a..cd9c4a0b5e 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -27,6 +27,7 @@ #include "movenc.h" #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "avio.h" #include "isom.h" @@ -1911,6 +1912,9 @@ static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMa static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi) { +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; +int size; + avio_wb32(pb, 32); /* size = 8 + 24 */ if (dovi->dv_profile > 10) ffio_wfourcc(pb, "dvwC"); @@ -1918,23 +1922,11 @@ static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDe ffio_wfourcc(pb, "dvvC"); else ffio_wfourcc(pb, "dvcC"); -avio_w8(pb, dovi->dv_version_major); -avio_w8(pb, dovi->dv_version_minor); -avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) | - (dovi->rpu_present_flag << 2) | (dovi->el_present_flag << 1) | - dovi->bl_present_flag); -avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0); - -ffio_fill(pb, 0, 4 * 4); /* reserved */ -av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? "dvvC" : "dvcC"), - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); + +size = ff_isom_put_dvcc_dvvc(s, buf, sizeof(buf), dovi); + +avio_write(pb, buf, size); + return 32; /* 8 + 24 */ } -- 2.33.1 ___ 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".
[FFmpeg-devel] [PATCH] fate: Add regression tests for AVDOVIDecoderConfigurationRecord side data
Signed-off-by: quietvoid --- Files are available here: https://drive.google.com/drive/folders/1NDhtSoJ-mP5Yi62V6j1wjjPJNq84nP3J They're all blank frames encoded with x265, remuxed with FFmpeg after the mov box is added by dlb_mp4base. Let me know if the hosting is not appropriate. I thought it was better than zipping everything. --- tests/fate/mov.mak | 17 tests/fate/mpegts.mak | 2 + tests/ref/fate/mov-dovi-config-profile5| 13 ++ tests/ref/fate/mov-dovi-config-profile7| 15 +++ tests/ref/fate/mov-dovi-config-profile81 | 13 ++ tests/ref/fate/mov-dovi-config-profile84 | 22 ++ tests/ref/fate/mov-dovi-write-config | 49 ++ tests/ref/fate/mpegts-dovi-config-profile7 | 15 +++ 8 files changed, 146 insertions(+) create mode 100644 tests/ref/fate/mov-dovi-config-profile5 create mode 100644 tests/ref/fate/mov-dovi-config-profile7 create mode 100644 tests/ref/fate/mov-dovi-config-profile81 create mode 100644 tests/ref/fate/mov-dovi-config-profile84 create mode 100644 tests/ref/fate/mov-dovi-write-config create mode 100644 tests/ref/fate/mpegts-dovi-config-profile7 diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index 5ca992e181..8ef7cb1edf 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -145,6 +145,23 @@ FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ += fate-mov-mp4-disposition-mpegts-remux fate-mov-mp4-disposition-mpegts-remux: CMD = transcode mpegts $(TARGET_SAMPLES)/mpegts/pmtchange.ts mp4 "-map 0:1 -map 0:2 -c copy -disposition:a:0 +hearing_impaired" "-map 0 -c copy" "" "-of json -show_entries stream_disposition:stream=index" +# Tests for AVDOVIDecoderConfigurationRecord parsing in mov +FATE_MOV_FFMPEG_FFPROBE-$(call DEMDEC, MOV) \ + += fate-mov-dovi-config-profile5 \ + fate-mov-dovi-config-profile7 \ + fate-mov-dovi-config-profile81 \ + fate-mov-dovi-config-profile84 +fate-mov-dovi-config-profile5: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mov/dovi-p5.mp4 +fate-mov-dovi-config-profile7: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mov/dovi-p7.mp4 +fate-mov-dovi-config-profile81: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mov/dovi-p81.mp4 +fate-mov-dovi-config-profile84: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/hevc/dv84.mov + +FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ + MPEGTS_DEMUXER MOV_DEMUXER \ + MP4_MUXER FRAMECRC_MUXER) \ + += fate-mov-dovi-write-config +fate-mov-dovi-write-config: CMD = transcode mpegts $(TARGET_SAMPLES)/mpegts/dovi-p7.ts mp4 "-map 0:0 -map 0:1 -c copy -strict unofficial" "-map 0 -c copy" "" "-show_entries stream_side_data_list -select_streams v -v 0" + FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MOV_FFMPEG_FFPROBE-yes) fate-mov: $(FATE_MOV) $(FATE_MOV_FFPROBE) $(FATE_MOV_FASTSTART) $(FATE_MOV_FFMPEG_FFPROBE-yes) diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak index bbcbfc47b2..1ee44ff2a0 100644 --- a/tests/fate/mpegts.mak +++ b/tests/fate/mpegts.mak @@ -19,6 +19,8 @@ FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-probe-pmt-merge fate-mpegts-probe-pmt-merge: SRC = $(TARGET_SAMPLES)/mpegts/pmtchange.ts fate-mpegts-probe-pmt-merge: CMD = run $(PROBE_CODEC_NAME_COMMAND) -merge_pmt_versions 1 -i "$(SRC)" +FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-dovi-config-profile7 +fate-mpegts-dovi-config-profile7: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mpegts/dovi-p7.ts FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROBE-yes) diff --git a/tests/ref/fate/mov-dovi-config-profile5 b/tests/ref/fate/mov-dovi-config-profile5 new file mode 100644 index 00..a27976b71a --- /dev/null +++ b/tests/ref/fate/mov-dovi-config-profile5 @@ -0,0 +1,13 @@ +[STREAM] +[SIDE_DATA] +side_data_type=DOVI configuration record +dv_version_major=1 +dv_version_minor=0 +dv_profile=5 +dv_level=4 +rpu_present_flag=1 +el_present_flag=0 +bl_present_flag=1 +dv_bl_signal_compatibility_id=0 +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/mov-dovi-config-profile7 b/tests/ref/fate/mov-dovi-config-profile7 new file mode 100644 index 00..1d8a4b6828 --- /dev/null +++ b/tests/ref/fate/mov-dovi-config-profile7 @@ -0,0 +1,15 @@ +[STREAM] +[/STREAM] +[STREAM] +[SIDE_DATA] +side_data_t
Re: [FFmpeg-devel] [PATCH v7 0/4] Add support for Matroska BlockAdditionMapping elements
> > This patch set adds support for reading/writing the Matroska > BlockAdditionMapping > elements, as well as for reading/writing dvcC/dvvC blocks in Matroska. > > Created utility functions to read/write Dolby Vision boxes for ISOM. > This was done to avoid duplicating the code, as the Matroska blocks and MOV > boxes > follow the same specification, defined by Dolby. > > Refactored the reading/writing in mov/movenc to use the new dovi_isom > functions. > > Differences compared to v6: > - Dropped the avformat/mpegts patch as suggested, because the specification > is different from the ISOM specification defined by Dolby. > - Added a patch to refactor avformat/movenc to further reduce the duplicated > code. The implementation in dovi_isom is the same. > - Moved init_put_bits after the size validation in ff_isom_put_dvcc_dvvc. > - Added dvwC to the ff_isom_put_dvcc_dvvc logging. > > quietvoid (4): > avformat/dovi_isom: Implement Dolby Vision configuration > parsing/writing > avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements > avformat/mov: Refactor mov_read_dvcc_dvvc to use > ff_isom_parse_dvcc_dvvc > avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use > ff_isom_put_dvcc_dvvc > > libavformat/Makefile | 4 +- > libavformat/dovi_isom.c | 121 ++ > libavformat/dovi_isom.h | 35 +++ > libavformat/matroska.h| 9 +++ > libavformat/matroskadec.c | 58 +- > libavformat/matroskaenc.c | 45 ++ > libavformat/mov.c | 50 +++- > libavformat/movenc.c | 26 +++- > 8 files changed, 286 insertions(+), 62 deletions(-) > create mode 100644 libavformat/dovi_isom.c > create mode 100644 libavformat/dovi_isom.h > > Ping. I've made a separate patch for regression tests for mov here: https://patchwork.ffmpeg.org/project/ffmpeg/patch/20211126170534.2041327-1-tcchlis...@gmail.com The tests are all passing with the changes from this patch set. ___ 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".
[FFmpeg-devel] [PATCH v8 0/5] Add support for Matroska BlockAdditionMapping elements
This patch set adds support for reading/writing the Matroska BlockAdditionMapping elements, as well as for reading/writing dvcC/dvvC blocks in Matroska. Created utility functions to read/write Dolby Vision boxes for ISOM. This was done to avoid duplicating the code, as the Matroska blocks and MOV boxes follow the same specification, defined by Dolby. Refactored the reading/writing in mov/movenc to use the new dovi_isom functions. v7: https://ffmpeg.org/pipermail/ffmpeg-devel/2021-October/287388.html Changes since v7: - Added original author of the ff_isom_parse_dvcc_dvvc implementation in the file header. - Added tests for reading/writing block addition mapping elements. quietvoid (5): avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc fate/matroska: Add tests for reading/writing BlockAdditionMapping elements libavformat/Makefile | 4 +- libavformat/dovi_isom.c | 123 ++ libavformat/dovi_isom.h | 35 +++ libavformat/matroska.h | 9 + libavformat/matroskadec.c| 58 - libavformat/matroskaenc.c| 45 libavformat/mov.c| 50 + libavformat/movenc.c | 26 +-- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 11 files changed, 533 insertions(+), 62 deletions(-) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v8 1/5] avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing
Both parse/write implementations are based on mov/movenc. This only adds support for the "Dolby Vision configuration box". Other configuration boxes, such as "Dolby Vision enhancement layer configuration box" are not supported. The new functions will be used to implement parsing/writing the DOVI config for Matroska, as well as to refactor both mov/movenc to use dovi_isom functions. Signed-off-by: quietvoid --- libavformat/dovi_isom.c | 123 libavformat/dovi_isom.h | 35 2 files changed, 158 insertions(+) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..679c913730 --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,123 @@ +/* + * DOVI ISO Media common code + * + * Copyright (c) 2020 Vacing Fang + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "libavcodec/put_bits.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id); + +return 0; +} + +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], uint64_t size, + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; + +if (size < ISOM_DVCC_DVVC_SIZE) +return AVERROR(EINVAL); + +init_put_bits(&pb, out, size); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ + +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " + &q
[FFmpeg-devel] [PATCH v8 2/5] avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements
From: quietvoid Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data. The configuration block is written when muxing into Matroska, if DOVI side data is present for the track. Most of the Matroska element parsing is based on Plex's FFmpeg source code. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 9 ++ libavformat/matroskadec.c | 58 +-- libavformat/matroskaenc.c | 45 ++ 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index 2b5caf9d33..bd12562a24 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -314,11 +314,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..16491aae22 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB @@ -385,4 +392,6 @@ extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_P int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); +#define DVCC_DVVC_BLOCK_TYPE_NAME "Dolby Vision configuration" + #endif /* AVFORMAT_MATROSKA_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index a4bbbe954e..6ce553205d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -53,6 +53,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "internal.h" #include "isom.h" #include "matroska.h" @@ -239,6 +240,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +277,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +428,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +579,14 @@ static EbmlSyntax matroska_t
[FFmpeg-devel] [PATCH v8 3/5] avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc
From: quietvoid To avoid duplicating code. The implementation in dovi_isom is identical. Signed-off-by: quietvoid --- libavformat/mov.c | 50 +-- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 5c74d099da..b5f974fe05 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -55,6 +55,7 @@ #include "avformat.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "isom.h" #include "libavcodec/get_bits.h" @@ -7051,58 +7052,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > ISOM_DVCC_DVVC_SIZE) { +read_size = ISOM_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = avio_read(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); +read_size = ret; -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom) -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v8 4/5] avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc
From: quietvoid Improves code legibility by not using bit shifts. Also avoids duplicating the dvcC/dvvC ISOM box writing code. Signed-off-by: quietvoid --- libavformat/movenc.c | 26 +- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 38ff90833a..79f7d70747 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -27,6 +27,7 @@ #include "movenc.h" #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "avio.h" #include "isom.h" @@ -1911,6 +1912,9 @@ static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMa static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi) { +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; +int size; + avio_wb32(pb, 32); /* size = 8 + 24 */ if (dovi->dv_profile > 10) ffio_wfourcc(pb, "dvwC"); @@ -1918,23 +1922,11 @@ static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDe ffio_wfourcc(pb, "dvvC"); else ffio_wfourcc(pb, "dvcC"); -avio_w8(pb, dovi->dv_version_major); -avio_w8(pb, dovi->dv_version_minor); -avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) | - (dovi->rpu_present_flag << 2) | (dovi->el_present_flag << 1) | - dovi->bl_present_flag); -avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0); - -ffio_fill(pb, 0, 4 * 4); /* reserved */ -av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? "dvvC" : "dvcC"), - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); + +size = ff_isom_put_dvcc_dvvc(s, buf, sizeof(buf), dovi); + +avio_write(pb, buf, size); + return 32; /* 8 + 24 */ } -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v8 5/5] fate/matroska: Add tests for reading/writing BlockAdditionMapping elements
Tests the parsing and writing of AVDOVIDecoderConfigurationRecord, when it is present as a Dolby Vision configuration block addition mapping. Signed-off-by: quietvoid --- The required regression test file is available here: https://0x0.st/-hWK.mkv Should be moved to fate-suite/mkv/dovi-p5.mkv It is a blank frame encoded with x265. --- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 3 files changed, 245 insertions(+) create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak index e117a0f6a6..ec2a0607b2 100644 --- a/tests/fate/matroska.mak +++ b/tests/fate/matroska.mak @@ -138,6 +138,15 @@ FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL WEBVTT_DEMUXER \ += fate-webm-webvtt-remux fate-webm-webvtt-remux: CMD = transcode webvtt $(TARGET_SAMPLES)/sub/WebVTT_capability_tester.vtt webm "-map 0 -map 0 -map 0 -map 0 -c:s copy -disposition:0 original+descriptions+hearing_impaired -disposition:1 lyrics+default+metadata -disposition:2 comment+forced -disposition:3 karaoke+captions+dub" "-map 0:0 -map 0:1 -c copy" "" "-show_entries stream_disposition:stream=index,codec_name:packet=stream_index,pts:packet_side_data_list -show_data_hash CRC32" +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, MATROSKA_DEMUXER) += fate-matroska-dovi-config-profile5 +fate-matroska-dovi-config-profile5: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mkv/dovi-p5.mkv + +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ +MOV_DEMUXER MATROSKA_MUXER \ +FRAMECRC_MUXER) \ + += fate-matroska-dovi-write-config +fate-matroska-dovi-write-config: CMD = transcode mov $(TARGET_SAMPLES)/hevc/dv84.mov matroska "-c:v copy" "-map 0 -c copy" "" "-show_entries stream_side_data_list -select_streams v -v 0" + FATE_SAMPLES_AVCONV += $(FATE_MATROSKA-yes) FATE_SAMPLES_FFPROBE += $(FATE_MATROSKA_FFPROBE-yes) FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MATROSKA_FFMPEG_FFPROBE-yes) diff --git a/tests/ref/fate/matroska-dovi-config-profile5 b/tests/ref/fate/matroska-dovi-config-profile5 new file mode 100644 index 00..a27976b71a --- /dev/null +++ b/tests/ref/fate/matroska-dovi-config-profile5 @@ -0,0 +1,13 @@ +[STREAM] +[SIDE_DATA] +side_data_type=DOVI configuration record +dv_version_major=1 +dv_version_minor=0 +dv_profile=5 +dv_level=4 +rpu_present_flag=1 +el_present_flag=0 +bl_present_flag=1 +dv_bl_signal_compatibility_id=0 +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/matroska-dovi-write-config b/tests/ref/fate/matroska-dovi-write-config new file mode 100644 index 00..a253db9f00 --- /dev/null +++ b/tests/ref/fate/matroska-dovi-write-config @@ -0,0 +1,223 @@ +47d2c151ff02720fff7bd37b3028097e *tests/data/fate/matroska-dovi-write-config.matroska +3618445 tests/data/fate/matroska-dovi-write-config.matroska +#extradata 0: 551, 0xa18acf66 +#tb 0: 1/1000 +#media_type 0: video +#codec_id 0: hevc +#dimensions 0: 1920x1080 +#sar 0: 0/1 +#tb 1: 1/1000 +#media_type 1: audio +#codec_id 1: ac3 +#sample_rate 1: 44100 +#channel_layout 1: 3 +#channel_layout_name 1: stereo +0,-67, 0, 33,63375, 0xc76606ab, S=1,8 +0,-34,133, 33,46706, 0x0e08a7e5, F=0x0 +0, 0, 73, 33,29766, 0x753c031a, F=0x0 +1, 0, 0, 34, 834, 0x6740ac04 +1, 35, 35, 34, 836, 0xe29a9a24 +0, 39, 39, 33,19409, 0x4b948b6c, F=0x0 +1, 70, 70, 34, 836, 0xf7329e5f +0, 73,106, 33,21086, 0x1b9412ce, F=0x0 +1,105,105, 34, 836, 0x9622a243 +0,106,273, 33,62043, 0xc2356b56, F=0x0 +0,133,206, 33,36175, 0x0a7df38c, F=0x0 +1,140,140, 34, 836, 0xb2d497c5 +0,173,173, 33,16028, 0xa57fcbe9, F=0x0 +1,174,174, 34, 836, 0x17c8980e +0,206,239, 33,15428, 0x9a91f357, F=0x0 +1,209,209, 34, 836, 0xfe288a7d +0,239,406, 33,66072, 0xa542b6d7, F=0x0 +1,244,244, 34, 836, 0x539e82b1 +0,273,339, 33,34985, 0xbfd8ff45, F=0x0 +1,279,279, 34, 836, 0x166291cb +0,306,306, 33,16036, 0xfc39c6ea, F=0x0 +1,314,314, 34, 836, 0x30127c33 +0,3
Re: [FFmpeg-devel] [PATCH v8 4/5] avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc
On Fri, Dec 3, 2021 at 8:19 PM wrote: > On Sat, Dec 04, 2021 at 02:09:04AM +0100, quietvoid wrote: > > From: quietvoid > > > > Improves code legibility by not using bit shifts. > > Also avoids duplicating the dvcC/dvvC ISOM box writing code. > > > > Signed-off-by: quietvoid > > --- > > libavformat/movenc.c | 26 +- > > 1 file changed, 9 insertions(+), 17 deletions(-) > > > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > > index 38ff90833a..79f7d70747 100644 > > --- a/libavformat/movenc.c > > +++ b/libavformat/movenc.c > > @@ -27,6 +27,7 @@ > > #include "movenc.h" > > #include "avformat.h" > > #include "avio_internal.h" > > +#include "dovi_isom.h" > > #include "riff.h" > > #include "avio.h" > > #include "isom.h" > > @@ -1911,6 +1912,9 @@ static int mov_write_sv3d_tag(AVFormatContext *s, > AVIOContext *pb, AVSphericalMa > > > > static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, > AVDOVIDecoderConfigurationRecord *dovi) > > { > > +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; > > +int size; > > + > > avio_wb32(pb, 32); /* size = 8 + 24 */ > > if (dovi->dv_profile > 10) > > ffio_wfourcc(pb, "dvwC"); > > @@ -1918,23 +1922,11 @@ static int > mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDe > > ffio_wfourcc(pb, "dvvC"); > > else > > ffio_wfourcc(pb, "dvcC"); > > -avio_w8(pb, dovi->dv_version_major); > > -avio_w8(pb, dovi->dv_version_minor); > > -avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) | > > - (dovi->rpu_present_flag << 2) | (dovi->el_present_flag << > 1) | > > - dovi->bl_present_flag); > > -avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0); > > - > > -ffio_fill(pb, 0, 4 * 4); /* reserved */ > > -av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: > %d, level: %d, " > > - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: > %d\n", > > - dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? > "dvvC" : "dvcC"), > > - dovi->dv_version_major, dovi->dv_version_minor, > > - dovi->dv_profile, dovi->dv_level, > > - dovi->rpu_present_flag, > > - dovi->el_present_flag, > > - dovi->bl_present_flag, > > - dovi->dv_bl_signal_compatibility_id); > > + > > +size = ff_isom_put_dvcc_dvvc(s, buf, sizeof(buf), dovi); > > I think you need check the return of ff_isom_put_dvcc_dvvc(). > > Wouldn't it necessarily return the constant ISOM_DVCC_DVVC_SIZE in this case? Since the only error condition is if the passed size is lower than that, but the buffer is constant sized. And the PutBitContext, being flushed, would return the same value. > > + > > +avio_write(pb, buf, size); > > + > > return 32; /* 8 + 24 */ > > } > > > > -- > > 2.34.1 > > > > ___ > > 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". > > -- > Thanks, > Limin Wang > ___ > 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". > ___ 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".
Re: [FFmpeg-devel] [PATCH v8 4/5] avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc
On Fri, Dec 3, 2021 at 8:40 PM wrote: > On Fri, Dec 03, 2021 at 08:27:06PM -0500, quietvoid wrote: > > On Fri, Dec 3, 2021 at 8:19 PM wrote: > > > > > On Sat, Dec 04, 2021 at 02:09:04AM +0100, quietvoid wrote: > > > > From: quietvoid > > > > > > > > Improves code legibility by not using bit shifts. > > > > Also avoids duplicating the dvcC/dvvC ISOM box writing code. > > > > > > > > Signed-off-by: quietvoid > > > > --- > > > > libavformat/movenc.c | 26 +- > > > > 1 file changed, 9 insertions(+), 17 deletions(-) > > > > > > > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > > > > index 38ff90833a..79f7d70747 100644 > > > > --- a/libavformat/movenc.c > > > > +++ b/libavformat/movenc.c > > > > @@ -27,6 +27,7 @@ > > > > #include "movenc.h" > > > > #include "avformat.h" > > > > #include "avio_internal.h" > > > > +#include "dovi_isom.h" > > > > #include "riff.h" > > > > #include "avio.h" > > > > #include "isom.h" > > > > @@ -1911,6 +1912,9 @@ static int mov_write_sv3d_tag(AVFormatContext > *s, > > > AVIOContext *pb, AVSphericalMa > > > > > > > > static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext > *pb, > > > AVDOVIDecoderConfigurationRecord *dovi) > > > > { > > > > +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; > > > > +int size; > > > > + > > > > avio_wb32(pb, 32); /* size = 8 + 24 */ > > > > if (dovi->dv_profile > 10) > > > > ffio_wfourcc(pb, "dvwC"); > > > > @@ -1918,23 +1922,11 @@ static int > > > mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDe > > > > ffio_wfourcc(pb, "dvvC"); > > > > else > > > > ffio_wfourcc(pb, "dvcC"); > > > > -avio_w8(pb, dovi->dv_version_major); > > > > -avio_w8(pb, dovi->dv_version_minor); > > > > -avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) | > > > > - (dovi->rpu_present_flag << 2) | > (dovi->el_present_flag << > > > 1) | > > > > - dovi->bl_present_flag); > > > > -avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0); > > > > - > > > > -ffio_fill(pb, 0, 4 * 4); /* reserved */ > > > > -av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, > profile: > > > %d, level: %d, " > > > > - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility > id: > > > %d\n", > > > > - dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? > > > "dvvC" : "dvcC"), > > > > - dovi->dv_version_major, dovi->dv_version_minor, > > > > - dovi->dv_profile, dovi->dv_level, > > > > - dovi->rpu_present_flag, > > > > - dovi->el_present_flag, > > > > - dovi->bl_present_flag, > > > > - dovi->dv_bl_signal_compatibility_id); > > > > + > > > > +size = ff_isom_put_dvcc_dvvc(s, buf, sizeof(buf), dovi); > > > > > > I think you need check the return of ff_isom_put_dvcc_dvvc(). > > > > > > > > Wouldn't it necessarily return the constant ISOM_DVCC_DVVC_SIZE in this > > case? > > yes, now it'll return negative error code in one error case. Why the out > parameter is > using array instead of pointer, as the size of buffer is one of parameters > also. > So if it's array, why it's necessary to check the size? > External users of the function can pass either an array or pointer. The size addition was suggested here: https://ffmpeg.org/pipermail/ffmpeg-devel/2021-September/285877.html So in the case a pointer is used, the size is necessary. > Since the only error condition is if the passed size is lower than that, > > but the buffer is constant sized. > > > > And the PutBitContext, being flushed, would return the same value. > > > > > > > > + > > > > +avio_write(pb, buf, size); > > > > + > > > > return 32; /* 8 + 24 */ > > > > } > > > > > > &
Re: [FFmpeg-devel] [PATCH v8 4/5] avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc
On Fri, Dec 3, 2021 at 8:51 PM quietvoid wrote: > > On Fri, Dec 3, 2021 at 8:40 PM wrote: > >> On Fri, Dec 03, 2021 at 08:27:06PM -0500, quietvoid wrote: >> > On Fri, Dec 3, 2021 at 8:19 PM wrote: >> > >> > > On Sat, Dec 04, 2021 at 02:09:04AM +0100, quietvoid wrote: >> > > > From: quietvoid >> > > > >> > > > Improves code legibility by not using bit shifts. >> > > > Also avoids duplicating the dvcC/dvvC ISOM box writing code. >> > > > >> > > > Signed-off-by: quietvoid >> > > > --- >> > > > libavformat/movenc.c | 26 +- >> > > > 1 file changed, 9 insertions(+), 17 deletions(-) >> > > > >> > > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c >> > > > index 38ff90833a..79f7d70747 100644 >> > > > --- a/libavformat/movenc.c >> > > > +++ b/libavformat/movenc.c >> > > > @@ -27,6 +27,7 @@ >> > > > #include "movenc.h" >> > > > #include "avformat.h" >> > > > #include "avio_internal.h" >> > > > +#include "dovi_isom.h" >> > > > #include "riff.h" >> > > > #include "avio.h" >> > > > #include "isom.h" >> > > > @@ -1911,6 +1912,9 @@ static int mov_write_sv3d_tag(AVFormatContext >> *s, >> > > AVIOContext *pb, AVSphericalMa >> > > > >> > > > static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext >> *pb, >> > > AVDOVIDecoderConfigurationRecord *dovi) >> > > > { >> > > > +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; >> > > > +int size; >> > > > + >> > > > avio_wb32(pb, 32); /* size = 8 + 24 */ >> > > > if (dovi->dv_profile > 10) >> > > > ffio_wfourcc(pb, "dvwC"); >> > > > @@ -1918,23 +1922,11 @@ static int >> > > mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDe >> > > > ffio_wfourcc(pb, "dvvC"); >> > > > else >> > > > ffio_wfourcc(pb, "dvcC"); >> > > > -avio_w8(pb, dovi->dv_version_major); >> > > > -avio_w8(pb, dovi->dv_version_minor); >> > > > -avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) | >> > > > - (dovi->rpu_present_flag << 2) | >> (dovi->el_present_flag << >> > > 1) | >> > > > - dovi->bl_present_flag); >> > > > -avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0); >> > > > - >> > > > -ffio_fill(pb, 0, 4 * 4); /* reserved */ >> > > > -av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, >> profile: >> > > %d, level: %d, " >> > > > - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility >> id: >> > > %d\n", >> > > > - dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? >> > > "dvvC" : "dvcC"), >> > > > - dovi->dv_version_major, dovi->dv_version_minor, >> > > > - dovi->dv_profile, dovi->dv_level, >> > > > - dovi->rpu_present_flag, >> > > > - dovi->el_present_flag, >> > > > - dovi->bl_present_flag, >> > > > - dovi->dv_bl_signal_compatibility_id); >> > > > + >> > > > +size = ff_isom_put_dvcc_dvvc(s, buf, sizeof(buf), dovi); >> > > >> > > I think you need check the return of ff_isom_put_dvcc_dvvc(). >> > > >> > > >> > Wouldn't it necessarily return the constant ISOM_DVCC_DVVC_SIZE in this >> > case? >> >> yes, now it'll return negative error code in one error case. Why the out >> parameter is >> using array instead of pointer, as the size of buffer is one of >> parameters also. >> So if it's array, why it's necessary to check the size? >> > > External users of the function can pass either an array or pointer. > Actually this is not true, I was looking at the wrong code. I don't think the size is necessary, then. The size addition was suggested here: > https://ffmpeg.org/pipermail/f
[FFmpeg-devel] [PATCH v9 0/5] Add support for Matroska BlockAdditionMapping elements
This patch set adds support for reading/writing the Matroska BlockAdditionMapping elements, as well as for reading/writing dvcC/dvvC blocks in Matroska. Created utility functions to read/write Dolby Vision boxes for ISOM. This was done to avoid duplicating the code, as the Matroska blocks and MOV boxes follow the same specification, defined by Dolby. Refactored the reading/writing in mov/movenc to use the new dovi_isom functions. v8: https://ffmpeg.org/pipermail/ffmpeg-devel/2021-December/288819.html Changes since v8: - Removed size argument from ff_isom_put_dvcc_dvvc, and changed the return type to void. The function always writes a constant number of bytes. quietvoid (5): avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc fate/matroska: Add tests for reading/writing BlockAdditionMapping elements libavformat/Makefile | 4 +- libavformat/dovi_isom.c | 118 ++ libavformat/dovi_isom.h | 35 +++ libavformat/matroska.h | 9 + libavformat/matroskadec.c| 58 - libavformat/matroskaenc.c| 40 libavformat/mov.c| 50 + libavformat/movenc.c | 24 +- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 11 files changed, 521 insertions(+), 62 deletions(-) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v9 1/5] avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing
Both parse/write implementations are based on mov/movenc. This only adds support for the "Dolby Vision configuration box". Other configuration boxes, such as "Dolby Vision enhancement layer configuration box" are not supported. The new functions will be used to implement parsing/writing the DOVI config for Matroska, as well as to refactor both mov/movenc to use dovi_isom functions. Signed-off-by: quietvoid --- libavformat/dovi_isom.c | 118 libavformat/dovi_isom.h | 35 2 files changed, 153 insertions(+) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..262d7e37ba --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,118 @@ +/* + * DOVI ISO Media common code + * + * Copyright (c) 2020 Vacing Fang + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "libavcodec/put_bits.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id); + +return 0; +} + +void ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; + +init_put_bits(&pb, out, ISOM_DVCC_DVVC_SIZE); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ + +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
[FFmpeg-devel] [PATCH v9 2/5] avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements
Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data. The configuration block is written when muxing into Matroska, if DOVI side data is present for the track. Most of the Matroska element parsing is based on Plex's FFmpeg source code. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 9 ++ libavformat/matroskadec.c | 58 +-- libavformat/matroskaenc.c | 40 +++ 4 files changed, 107 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index 2b5caf9d33..bd12562a24 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -314,11 +314,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..16491aae22 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB @@ -385,4 +392,6 @@ extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_P int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); +#define DVCC_DVVC_BLOCK_TYPE_NAME "Dolby Vision configuration" + #endif /* AVFORMAT_MATROSKA_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index a4bbbe954e..6ce553205d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -53,6 +53,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "internal.h" #include "isom.h" #include "matroska.h" @@ -239,6 +240,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +277,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +428,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +579,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_
[FFmpeg-devel] [PATCH v9 3/5] avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc
To avoid duplicating code. The implementation in dovi_isom is identical. Signed-off-by: quietvoid --- libavformat/mov.c | 50 +-- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 5c74d099da..b5f974fe05 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -55,6 +55,7 @@ #include "avformat.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "isom.h" #include "libavcodec/get_bits.h" @@ -7051,58 +7052,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > ISOM_DVCC_DVVC_SIZE) { +read_size = ISOM_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = avio_read(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); +read_size = ret; -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom) -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v9 4/5] avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc
Improves code legibility by not using bit shifts. Also avoids duplicating the dvcC/dvvC ISOM box writing code. Signed-off-by: quietvoid --- libavformat/movenc.c | 24 +++- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 38ff90833a..208378fc11 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -27,6 +27,7 @@ #include "movenc.h" #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "avio.h" #include "isom.h" @@ -1911,6 +1912,8 @@ static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMa static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi) { +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; + avio_wb32(pb, 32); /* size = 8 + 24 */ if (dovi->dv_profile > 10) ffio_wfourcc(pb, "dvwC"); @@ -1918,23 +1921,10 @@ static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDe ffio_wfourcc(pb, "dvvC"); else ffio_wfourcc(pb, "dvcC"); -avio_w8(pb, dovi->dv_version_major); -avio_w8(pb, dovi->dv_version_minor); -avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) | - (dovi->rpu_present_flag << 2) | (dovi->el_present_flag << 1) | - dovi->bl_present_flag); -avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0); - -ffio_fill(pb, 0, 4 * 4); /* reserved */ -av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? "dvvC" : "dvcC"), - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); + +ff_isom_put_dvcc_dvvc(s, buf, dovi); +avio_write(pb, buf, sizeof(buf)); + return 32; /* 8 + 24 */ } -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v9 5/5] fate/matroska: Add tests for reading/writing BlockAdditionMapping elements
Tests the parsing and writing of AVDOVIDecoderConfigurationRecord, when it is present as a Dolby Vision configuration block addition mapping. Signed-off-by: quietvoid --- The required regression test file is available here: https://0x0.st/-hWK.mkv Should be moved to fate-suite/mkv/dovi-p5.mkv It is a blank frame encoded with x265. --- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 3 files changed, 245 insertions(+) create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak index e117a0f6a6..ec2a0607b2 100644 --- a/tests/fate/matroska.mak +++ b/tests/fate/matroska.mak @@ -138,6 +138,15 @@ FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL WEBVTT_DEMUXER \ += fate-webm-webvtt-remux fate-webm-webvtt-remux: CMD = transcode webvtt $(TARGET_SAMPLES)/sub/WebVTT_capability_tester.vtt webm "-map 0 -map 0 -map 0 -map 0 -c:s copy -disposition:0 original+descriptions+hearing_impaired -disposition:1 lyrics+default+metadata -disposition:2 comment+forced -disposition:3 karaoke+captions+dub" "-map 0:0 -map 0:1 -c copy" "" "-show_entries stream_disposition:stream=index,codec_name:packet=stream_index,pts:packet_side_data_list -show_data_hash CRC32" +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, MATROSKA_DEMUXER) += fate-matroska-dovi-config-profile5 +fate-matroska-dovi-config-profile5: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mkv/dovi-p5.mkv + +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ +MOV_DEMUXER MATROSKA_MUXER \ +FRAMECRC_MUXER) \ + += fate-matroska-dovi-write-config +fate-matroska-dovi-write-config: CMD = transcode mov $(TARGET_SAMPLES)/hevc/dv84.mov matroska "-c:v copy" "-map 0 -c copy" "" "-show_entries stream_side_data_list -select_streams v -v 0" + FATE_SAMPLES_AVCONV += $(FATE_MATROSKA-yes) FATE_SAMPLES_FFPROBE += $(FATE_MATROSKA_FFPROBE-yes) FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MATROSKA_FFMPEG_FFPROBE-yes) diff --git a/tests/ref/fate/matroska-dovi-config-profile5 b/tests/ref/fate/matroska-dovi-config-profile5 new file mode 100644 index 00..a27976b71a --- /dev/null +++ b/tests/ref/fate/matroska-dovi-config-profile5 @@ -0,0 +1,13 @@ +[STREAM] +[SIDE_DATA] +side_data_type=DOVI configuration record +dv_version_major=1 +dv_version_minor=0 +dv_profile=5 +dv_level=4 +rpu_present_flag=1 +el_present_flag=0 +bl_present_flag=1 +dv_bl_signal_compatibility_id=0 +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/matroska-dovi-write-config b/tests/ref/fate/matroska-dovi-write-config new file mode 100644 index 00..a253db9f00 --- /dev/null +++ b/tests/ref/fate/matroska-dovi-write-config @@ -0,0 +1,223 @@ +47d2c151ff02720fff7bd37b3028097e *tests/data/fate/matroska-dovi-write-config.matroska +3618445 tests/data/fate/matroska-dovi-write-config.matroska +#extradata 0: 551, 0xa18acf66 +#tb 0: 1/1000 +#media_type 0: video +#codec_id 0: hevc +#dimensions 0: 1920x1080 +#sar 0: 0/1 +#tb 1: 1/1000 +#media_type 1: audio +#codec_id 1: ac3 +#sample_rate 1: 44100 +#channel_layout 1: 3 +#channel_layout_name 1: stereo +0,-67, 0, 33,63375, 0xc76606ab, S=1,8 +0,-34,133, 33,46706, 0x0e08a7e5, F=0x0 +0, 0, 73, 33,29766, 0x753c031a, F=0x0 +1, 0, 0, 34, 834, 0x6740ac04 +1, 35, 35, 34, 836, 0xe29a9a24 +0, 39, 39, 33,19409, 0x4b948b6c, F=0x0 +1, 70, 70, 34, 836, 0xf7329e5f +0, 73,106, 33,21086, 0x1b9412ce, F=0x0 +1,105,105, 34, 836, 0x9622a243 +0,106,273, 33,62043, 0xc2356b56, F=0x0 +0,133,206, 33,36175, 0x0a7df38c, F=0x0 +1,140,140, 34, 836, 0xb2d497c5 +0,173,173, 33,16028, 0xa57fcbe9, F=0x0 +1,174,174, 34, 836, 0x17c8980e +0,206,239, 33,15428, 0x9a91f357, F=0x0 +1,209,209, 34, 836, 0xfe288a7d +0,239,406, 33,66072, 0xa542b6d7, F=0x0 +1,244,244, 34, 836, 0x539e82b1 +0,273,339, 33,34985, 0xbfd8ff45, F=0x0 +1,279,279, 34, 836, 0x166291cb +0,306,306, 33,16036, 0xfc39c6ea, F=0x0 +1,314,314, 34, 836, 0x30127c33 +0,3
Re: [FFmpeg-devel] [PATCH v3] avcodec/dovi_rpu: verify RPU data CRC32
On 09/08/2023 13.46, quietvoid wrote: The Dolby Vision RPU contains a CRC32 to validate the payload against. The implementation is CRC32/MPEG-2. The CRC is only verified with the AV_EF_CRCCHECK flag. Signed-off-by: quietvoid --- libavcodec/dovi_rpu.c | 46 --- libavcodec/dovi_rpu.h | 3 ++- libavcodec/hevcdec.c | 3 ++- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index dd38936552..1dfeee7564 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -22,6 +22,7 @@ */ #include "libavutil/buffer.h" +#include "libavutil/crc.h" #include "dovi_rpu.h" #include "golomb.h" @@ -191,13 +192,17 @@ static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader * } \ } while (0) -int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) +int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, + int err_recognition) { AVDOVIRpuDataHeader *hdr = &s->header; GetBitContext *gb = &(GetBitContext){0}; DOVIVdrRef *vdr; int ret; +size_t actual_rpu_size; +uint8_t trailing_zeroes = 0; + uint8_t nal_prefix; uint8_t rpu_type; uint8_t vdr_seq_info_present; @@ -205,7 +210,22 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) uint8_t use_prev_vdr_rpu; uint8_t use_nlq; uint8_t profile; -if ((ret = init_get_bits8(gb, rpu, rpu_size)) < 0) + +uint32_t rpu_data_crc32; +uint32_t computed_crc32; + +for (int i = rpu_size - 1; i > 0; i--) { +if (!rpu[i]) { +trailing_zeroes++; +} else { +break; +} +} + +actual_rpu_size = rpu_size - trailing_zeroes; + +/* Exclude trailing byte (0x80) from reader */ +if ((ret = init_get_bits8(gb, rpu, actual_rpu_size - 1)) < 0) return ret; /* RPU header, common values */ @@ -440,7 +460,27 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) color->source_diagonal = get_bits(gb, 10); } -/* FIXME: verify CRC32, requires implementation of AV_CRC_32_MPEG_2 */ +if (!(err_recognition & AV_EF_CRCCHECK)) +return 0; + +/* Skip unsupported until CRC32 */ +skip_bits_long(gb, get_bits_left(gb) - 32); + +rpu_data_crc32 = get_bits_long(gb, 32); + +/* Verify CRC32, buffer excludes the prefix, CRC32 and trailing byte */ +computed_crc32 = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), + -1, rpu + 1, actual_rpu_size - 6)); + +if (rpu_data_crc32 != computed_crc32) { +av_log(s->logctx, AV_LOG_ERROR, + "RPU CRC mismatch! Expected %"PRIu32", received %"PRIu32"\n", + rpu_data_crc32, computed_crc32); + +if (err_recognition & AV_EF_EXPLODE) +goto fail; +} + return 0; fail: diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index f6ca5bbbc5..2b993a72c6 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -77,7 +77,8 @@ void ff_dovi_update_cfg(DOVIContext *s, const AVDOVIDecoderConfigurationRecord * * * Returns 0 or an error code. */ -int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size); +int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, + int err_recognition); /** * Attach the decoded AVDOVIMetadata as side data to an AVFrame. diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index df40c91ba6..81b1a84625 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -3182,7 +3182,8 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) return AVERROR(ENOMEM); memcpy(s->rpu_buf->data, nal->raw_data + 2, nal->raw_size - 2); -ret = ff_dovi_rpu_parse(&s->dovi_ctx, nal->data + 2, nal->size - 2); +ret = ff_dovi_rpu_parse(&s->dovi_ctx, nal->data + 2, nal->size - 2, +s->avctx->err_recognition); if (ret < 0) { av_buffer_unref(&s->rpu_buf); av_log(s->avctx, AV_LOG_WARNING, "Error parsing DOVI NAL unit.\n"); Bumping this patch. ___ 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".
Re: [FFmpeg-devel] [PATCH v3] avcodec/dovi_rpu: verify RPU data CRC32
On 26/10/2023 17.44, Michael Niedermayer wrote: On Wed, Aug 09, 2023 at 01:46:57PM -0400, quietvoid wrote: The Dolby Vision RPU contains a CRC32 to validate the payload against. The implementation is CRC32/MPEG-2. The CRC is only verified with the AV_EF_CRCCHECK flag. Signed-off-by: quietvoid --- libavcodec/dovi_rpu.c | 46 --- libavcodec/dovi_rpu.h | 3 ++- libavcodec/hevcdec.c | 3 ++- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index dd38936552..1dfeee7564 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -22,6 +22,7 @@ */ #include "libavutil/buffer.h" +#include "libavutil/crc.h" #include "dovi_rpu.h" #include "golomb.h" @@ -191,13 +192,17 @@ static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader * } \ } while (0) -int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) +int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, + int err_recognition) { AVDOVIRpuDataHeader *hdr = &s->header; GetBitContext *gb = &(GetBitContext){0}; DOVIVdrRef *vdr; int ret; +size_t actual_rpu_size; +uint8_t trailing_zeroes = 0; + uint8_t nal_prefix; uint8_t rpu_type; uint8_t vdr_seq_info_present; @@ -205,7 +210,22 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) uint8_t use_prev_vdr_rpu; uint8_t use_nlq; uint8_t profile; -if ((ret = init_get_bits8(gb, rpu, rpu_size)) < 0) + +uint32_t rpu_data_crc32; +uint32_t computed_crc32; + +for (int i = rpu_size - 1; i > 0; i--) { +if (!rpu[i]) { +trailing_zeroes++; +} else { +break; +} +} + +actual_rpu_size = rpu_size - trailing_zeroes; + +/* Exclude trailing byte (0x80) from reader */ +if ((ret = init_get_bits8(gb, rpu, actual_rpu_size - 1)) < 0) return ret; /* RPU header, common values */ @@ -440,7 +460,27 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) color->source_diagonal = get_bits(gb, 10); } -/* FIXME: verify CRC32, requires implementation of AV_CRC_32_MPEG_2 */ +if (!(err_recognition & AV_EF_CRCCHECK)) +return 0; + +/* Skip unsupported until CRC32 */ +skip_bits_long(gb, get_bits_left(gb) - 32); + +rpu_data_crc32 = get_bits_long(gb, 32); + +/* Verify CRC32, buffer excludes the prefix, CRC32 and trailing byte */ +computed_crc32 = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), + -1, rpu + 1, actual_rpu_size - 6)); + +if (rpu_data_crc32 != computed_crc32) { +av_log(s->logctx, AV_LOG_ERROR, + "RPU CRC mismatch! Expected %"PRIu32", received %"PRIu32"\n", + rpu_data_crc32, computed_crc32); + +if (err_recognition & AV_EF_EXPLODE) +goto fail; +} (correctly designed) CRCs have the beautifull symmetry that you can merge the crc32 value into the crc computation and then a 0 means no CRC missmatch (there are many other cool properties but this one allows to simplify the code) This works too: (and is simpler) /* Skip unsupported until CRC32 */ skip_bits_long(gb, get_bits_left(gb)); /* Verify CRC32, buffer excludes the prefix, CRC32 and trailing byte */ computed_crc32 = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, rpu + 1, actual_rpu_size - 2)); if (computed_crc32) { av_log(s->logctx, AV_LOG_ERROR, "RPU CRC mismatch! %"PRIX32"\n", computed_crc32); if (err_recognition & AV_EF_EXPLODE) goto fail; } Hi Michael. I like the idea and it's a cool property. However the then printed CRC on mismatch is not a useful value, so I'm unsure if it's better to simplify here. I like having the expected CRC logged here. Thanks. ___ 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".
[FFmpeg-devel] [PATCH] avcodec/dovi_rpu: verify RPU data CRC32
The Dolby Vision RPU contains a CRC32 to validate the payload against. It must be an identical match for the metadata to be used. The implementation is CRC32/MPEG-2. Signed-off-by: quietvoid --- libavcodec/dovi_rpu.c | 37 +++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index dd38936552..00f811e3a6 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -22,6 +22,7 @@ */ #include "libavutil/buffer.h" +#include "libavutil/crc.h" #include "dovi_rpu.h" #include "golomb.h" @@ -198,6 +199,9 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) DOVIVdrRef *vdr; int ret; +size_t actual_rpu_size; +uint8_t trailing_zeroes = 0; + uint8_t nal_prefix; uint8_t rpu_type; uint8_t vdr_seq_info_present; @@ -205,7 +209,21 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) uint8_t use_prev_vdr_rpu; uint8_t use_nlq; uint8_t profile; -if ((ret = init_get_bits8(gb, rpu, rpu_size)) < 0) +uint32_t rpu_data_crc32; +uint32_t computed_crc32; + +for (int i = rpu_size - 1; i > 0; i--) { +if (!rpu[i]) { +trailing_zeroes++; +} else { +break; +} +} + +actual_rpu_size = rpu_size - trailing_zeroes; + +/* Exclude trailing byte (0x80) from reader */ +if ((ret = init_get_bits8(gb, rpu, actual_rpu_size - 1)) < 0) return ret; /* RPU header, common values */ @@ -440,7 +458,22 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) color->source_diagonal = get_bits(gb, 10); } -/* FIXME: verify CRC32, requires implementation of AV_CRC_32_MPEG_2 */ +/* Skip unsupported until CRC32 */ +skip_bits_long(gb, get_bits_left(gb) - 32); + +rpu_data_crc32 = get_bits_long(gb, 32); + +/* Verify CRC32, the buffer excludes the prefix, CRC32 and trailing byte */ +computed_crc32 = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, +rpu + 1, actual_rpu_size - 6)); + +if (rpu_data_crc32 != computed_crc32) { +av_log(s->logctx, AV_LOG_ERROR, + "Invalid RPU CRC32: Received %"PRIu32", expected %"PRIu32"\n", + computed_crc32, rpu_data_crc32); +goto fail; +} + return 0; fail: -- 2.41.0 ___ 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".
[FFmpeg-devel] [PATCH v2] avcodec/dovi_rpu: verify RPU data CRC32
The Dolby Vision RPU contains a CRC32 to validate the payload against. The implementation is CRC32/MPEG-2. The CRC is only verified with the AV_EF_CRCCHECK flag. Signed-off-by: quietvoid --- libavcodec/dovi_rpu.c | 45 --- libavcodec/dovi_rpu.h | 3 ++- libavcodec/hevcdec.c | 3 ++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index dd38936552..9ada0aceec 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -22,6 +22,7 @@ */ #include "libavutil/buffer.h" +#include "libavutil/crc.h" #include "dovi_rpu.h" #include "golomb.h" @@ -191,13 +192,17 @@ static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader * } \ } while (0) -int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) +int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, + int err_recognition) { AVDOVIRpuDataHeader *hdr = &s->header; GetBitContext *gb = &(GetBitContext){0}; DOVIVdrRef *vdr; int ret; +size_t actual_rpu_size; +uint8_t trailing_zeroes = 0; + uint8_t nal_prefix; uint8_t rpu_type; uint8_t vdr_seq_info_present; @@ -205,7 +210,22 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) uint8_t use_prev_vdr_rpu; uint8_t use_nlq; uint8_t profile; -if ((ret = init_get_bits8(gb, rpu, rpu_size)) < 0) + +uint32_t rpu_data_crc32; +uint32_t computed_crc32; + +for (int i = rpu_size - 1; i > 0; i--) { +if (!rpu[i]) { +trailing_zeroes++; +} else { +break; +} +} + +actual_rpu_size = rpu_size - trailing_zeroes; + +/* Exclude trailing byte (0x80) from reader */ +if ((ret = init_get_bits8(gb, rpu, actual_rpu_size - 1)) < 0) return ret; /* RPU header, common values */ @@ -440,7 +460,26 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) color->source_diagonal = get_bits(gb, 10); } -/* FIXME: verify CRC32, requires implementation of AV_CRC_32_MPEG_2 */ +/* Skip unsupported until CRC32 */ +skip_bits_long(gb, get_bits_left(gb) - 32); + +if (err_recognition & AV_EF_CRCCHECK) { +rpu_data_crc32 = get_bits_long(gb, 32); + +/* Verify CRC32, buffer excludes the prefix, CRC32 and trailing byte */ +computed_crc32 = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), + -1, rpu + 1, actual_rpu_size - 6)); + +if (rpu_data_crc32 != computed_crc32) { +av_log(s->logctx, AV_LOG_ERROR, + "RPU CRC mismatch! Expected %"PRIu32", received %"PRIu32"\n", + rpu_data_crc32, computed_crc32); + +if (err_recognition & AV_EF_EXPLODE) +goto fail; +} +} + return 0; fail: diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index f6ca5bbbc5..2b993a72c6 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -77,7 +77,8 @@ void ff_dovi_update_cfg(DOVIContext *s, const AVDOVIDecoderConfigurationRecord * * * Returns 0 or an error code. */ -int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size); +int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, + int err_recognition); /** * Attach the decoded AVDOVIMetadata as side data to an AVFrame. diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index df40c91ba6..81b1a84625 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -3182,7 +3182,8 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) return AVERROR(ENOMEM); memcpy(s->rpu_buf->data, nal->raw_data + 2, nal->raw_size - 2); -ret = ff_dovi_rpu_parse(&s->dovi_ctx, nal->data + 2, nal->size - 2); +ret = ff_dovi_rpu_parse(&s->dovi_ctx, nal->data + 2, nal->size - 2, +s->avctx->err_recognition); if (ret < 0) { av_buffer_unref(&s->rpu_buf); av_log(s->avctx, AV_LOG_WARNING, "Error parsing DOVI NAL unit.\n"); -- 2.41.0 ___ 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".
[FFmpeg-devel] [PATCH v3] avcodec/dovi_rpu: verify RPU data CRC32
The Dolby Vision RPU contains a CRC32 to validate the payload against. The implementation is CRC32/MPEG-2. The CRC is only verified with the AV_EF_CRCCHECK flag. Signed-off-by: quietvoid --- libavcodec/dovi_rpu.c | 46 --- libavcodec/dovi_rpu.h | 3 ++- libavcodec/hevcdec.c | 3 ++- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index dd38936552..1dfeee7564 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -22,6 +22,7 @@ */ #include "libavutil/buffer.h" +#include "libavutil/crc.h" #include "dovi_rpu.h" #include "golomb.h" @@ -191,13 +192,17 @@ static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader * } \ } while (0) -int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) +int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, + int err_recognition) { AVDOVIRpuDataHeader *hdr = &s->header; GetBitContext *gb = &(GetBitContext){0}; DOVIVdrRef *vdr; int ret; +size_t actual_rpu_size; +uint8_t trailing_zeroes = 0; + uint8_t nal_prefix; uint8_t rpu_type; uint8_t vdr_seq_info_present; @@ -205,7 +210,22 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) uint8_t use_prev_vdr_rpu; uint8_t use_nlq; uint8_t profile; -if ((ret = init_get_bits8(gb, rpu, rpu_size)) < 0) + +uint32_t rpu_data_crc32; +uint32_t computed_crc32; + +for (int i = rpu_size - 1; i > 0; i--) { +if (!rpu[i]) { +trailing_zeroes++; +} else { +break; +} +} + +actual_rpu_size = rpu_size - trailing_zeroes; + +/* Exclude trailing byte (0x80) from reader */ +if ((ret = init_get_bits8(gb, rpu, actual_rpu_size - 1)) < 0) return ret; /* RPU header, common values */ @@ -440,7 +460,27 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) color->source_diagonal = get_bits(gb, 10); } -/* FIXME: verify CRC32, requires implementation of AV_CRC_32_MPEG_2 */ +if (!(err_recognition & AV_EF_CRCCHECK)) +return 0; + +/* Skip unsupported until CRC32 */ +skip_bits_long(gb, get_bits_left(gb) - 32); + +rpu_data_crc32 = get_bits_long(gb, 32); + +/* Verify CRC32, buffer excludes the prefix, CRC32 and trailing byte */ +computed_crc32 = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), + -1, rpu + 1, actual_rpu_size - 6)); + +if (rpu_data_crc32 != computed_crc32) { +av_log(s->logctx, AV_LOG_ERROR, + "RPU CRC mismatch! Expected %"PRIu32", received %"PRIu32"\n", + rpu_data_crc32, computed_crc32); + +if (err_recognition & AV_EF_EXPLODE) +goto fail; +} + return 0; fail: diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index f6ca5bbbc5..2b993a72c6 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -77,7 +77,8 @@ void ff_dovi_update_cfg(DOVIContext *s, const AVDOVIDecoderConfigurationRecord * * * Returns 0 or an error code. */ -int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size); +int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, + int err_recognition); /** * Attach the decoded AVDOVIMetadata as side data to an AVFrame. diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index df40c91ba6..81b1a84625 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -3182,7 +3182,8 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) return AVERROR(ENOMEM); memcpy(s->rpu_buf->data, nal->raw_data + 2, nal->raw_size - 2); -ret = ff_dovi_rpu_parse(&s->dovi_ctx, nal->data + 2, nal->size - 2); +ret = ff_dovi_rpu_parse(&s->dovi_ctx, nal->data + 2, nal->size - 2, +s->avctx->err_recognition); if (ret < 0) { av_buffer_unref(&s->rpu_buf); av_log(s->avctx, AV_LOG_WARNING, "Error parsing DOVI NAL unit.\n"); -- 2.41.0 ___ 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".
Re: [FFmpeg-devel] [PATCH v2] avcodec/dovi_rpu: verify RPU data CRC32
On 09/08/2023 13.08, James Almer wrote: On 8/9/2023 2:05 PM, quietvoid wrote: The Dolby Vision RPU contains a CRC32 to validate the payload against. The implementation is CRC32/MPEG-2. The CRC is only verified with the AV_EF_CRCCHECK flag. Signed-off-by: quietvoid ---  libavcodec/dovi_rpu.c | 45 ---  libavcodec/dovi_rpu.h | 3 ++-  libavcodec/hevcdec.c | 3 ++-  3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index dd38936552..9ada0aceec 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -22,6 +22,7 @@   */   #include "libavutil/buffer.h" +#include "libavutil/crc.h"   #include "dovi_rpu.h"  #include "golomb.h" @@ -191,13 +192,17 @@ static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader * } \  } while (0)  -int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) +int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, + int err_recognition)  {  AVDOVIRpuDataHeader *hdr = &s->header;  GetBitContext *gb = &(GetBitContext){0};  DOVIVdrRef *vdr;  int ret;  +   size_t actual_rpu_size; +   uint8_t trailing_zeroes = 0; +  uint8_t nal_prefix;  uint8_t rpu_type;  uint8_t vdr_seq_info_present; @@ -205,7 +210,22 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size)  uint8_t use_prev_vdr_rpu;  uint8_t use_nlq;  uint8_t profile; -   if ((ret = init_get_bits8(gb, rpu, rpu_size)) < 0) + +   uint32_t rpu_data_crc32; +   uint32_t computed_crc32; + +   for (int i = rpu_size - 1; i > 0; i--) { +   if (!rpu[i]) { +   trailing_zeroes++; +   } else { +   break; +   } +   } + +   actual_rpu_size = rpu_size - trailing_zeroes; + +   /* Exclude trailing byte (0x80) from reader */ +   if ((ret = init_get_bits8(gb, rpu, actual_rpu_size - 1)) < 0)  return ret;   /* RPU header, common values */ @@ -440,7 +460,26 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size)  color->source_diagonal = get_bits(gb, 10);  }  -   /* FIXME: verify CRC32, requires implementation of AV_CRC_32_MPEG_2 */ +   /* Skip unsupported until CRC32 */ +   skip_bits_long(gb, get_bits_left(gb) - 32); This can be done after the err_recognition check. + +   if (err_recognition & AV_EF_CRCCHECK) { Do instead if (!(err_recognition & AV_EF_CRCCHECK))    return 0; To remove one level of indentation. Thanks, sent v3: https://ffmpeg.org/pipermail/ffmpeg-devel/2023-August/313141.html ___ 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".
Re: [FFmpeg-devel] [PATCH v2 08/10] avcodec: add external encoder libvvenc for H266/VVC
On 24/10/2022 10.06, Thomas Siedel wrote: Add external encoder VVenC for H266/VVC encoding. Register new encoder libvvencc Add libvvenc to wrap the vvenc interface into ffmpeg libvvenc implements encoder option: preset,qp,period,subjopt,vvenc-params,levelidc,tier Enable encoder by adding --enable-libvvenc in configure step Signed-off-by: Thomas Siedel --- configure | 5 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/libvvenc.c | 442 + 4 files changed, 449 insertions(+) create mode 100644 libavcodec/libvvenc.c diff --git a/configure b/configure index 978f15f772..f8f7965371 100755 --- a/configure +++ b/configure @@ -289,6 +289,7 @@ External library support: native implementation exists [no] --enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no] --enable-libvvdec enable VVC decoding via vvdec [no] + --enable-libvvenc enable VVC encoding via vvenc [no] --enable-libwebp enable WebP encoding via libwebp [no] --enable-libx264 enable H.264 encoding via x264 [no] --enable-libx265 enable HEVC encoding via x265 [no] @@ -1877,6 +1878,7 @@ EXTERNAL_LIBRARY_LIST=" libvorbis libvpx libvvdec + libvvenc libwebp libxml2 libzimg @@ -3409,6 +3411,8 @@ libvpx_vp9_decoder_deps="libvpx" libvpx_vp9_encoder_deps="libvpx" libvvdec_decoder_deps="libvvdec" libvvdec_decoder_select="vvc_mp4toannexb_bsf" +libvvenc_encoder_deps="libvvenc" +libvvenc_encoder_select="atsc_a53" libwebp_encoder_deps="libwebp" libwebp_anim_encoder_deps="libwebp" libx262_encoder_deps="libx262" @@ -6740,6 +6744,7 @@ enabled libvpx && { fi } enabled libvvdec && require_pkg_config libvvdec "libvvdec >= 1.6.0" "vvdec/vvdec.h" vvdec_get_version +enabled libvvenc && require_pkg_config libvvenc "libvvenc >= 1.6.1" "vvenc/vvenc.h" vvenc_get_version enabled libwebp && { enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion diff --git a/libavcodec/Makefile b/libavcodec/Makefile index f4cdbc9be1..badd266e66 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1105,6 +1105,7 @@ OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o libvpx.o OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o libvpx.o OBJS-$(CONFIG_LIBVVDEC_DECODER) += libvvdec.o vvc_parse_extradata.o vvc_paramset.o +OBJS-$(CONFIG_LIBVVENC_ENCODER) += libvvenc.o OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 9813b291f4..73c36f3134 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -794,6 +794,7 @@ extern const FFCodec ff_libvpx_vp8_decoder; extern FFCodec ff_libvpx_vp9_encoder; extern FFCodec ff_libvpx_vp9_decoder; extern const FFCodec ff_libvvdec_decoder; +extern const FFCodec ff_libvvenc_encoder; /* preferred over libwebp */ extern const FFCodec ff_libwebp_anim_encoder; extern const FFCodec ff_libwebp_encoder; diff --git a/libavcodec/libvvenc.c b/libavcodec/libvvenc.c new file mode 100644 index 00..508fe6ceff --- /dev/null +++ b/libavcodec/libvvenc.c @@ -0,0 +1,442 @@ +/* + * H.266 encoding using the VVenC library + * + * Copyright (C) 2022, Thomas Siedel + * + * 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 "config_components.h" + +#include +#include + +#include "avcodec.h" +#include "codec_internal.h" +#include "encode.h" +#include "internal.h" +#include "packet_internal.h" +#include "profiles.h" + +#include "libavutil/avutil.h" +#include "libavutil/pixdesc.h" +#include "libavutil/opt.h" +#include "libavutil/common.h" +#include "libavutil/imgutils.h" +#include "libavutil/frame.h" +#include "libavutil/log.h" + +typedef struct VVenCOptions { + int preset; // preset 0: faster 4: slower + int qp; // quantization parameter 0-63 + int subjectiveOptimization; // perceptually motivated QP adaptation, XPSNR based + int intraRefreshSec; // intra period/refresh in seconds + int levelIdc; // vvc level_idc + int tier; // vvc tier + AVDictionary *vvenc_opts; +} VVenCOptions; + +typedef struct VVenCContext { + AVClass *av_class; + VVenCOptions options; // encoder optio
Re: [FFmpeg-devel] [PATCH v9 3/5] avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc
On Tue, Dec 7, 2021 at 9:37 AM wrote: > > On Sun, Dec 05, 2021 at 06:35:33PM +0100, quietvoid wrote: > > To avoid duplicating code. The implementation in dovi_isom is identical. > > > > Signed-off-by: quietvoid > > --- > > libavformat/mov.c | 50 +-- > > 1 file changed, 9 insertions(+), 41 deletions(-) > > > > diff --git a/libavformat/mov.c b/libavformat/mov.c > > index 5c74d099da..b5f974fe05 100644 > > --- a/libavformat/mov.c > > +++ b/libavformat/mov.c > > @@ -55,6 +55,7 @@ > > #include "avformat.h" > > #include "internal.h" > > #include "avio_internal.h" > > +#include "dovi_isom.h" > > #include "riff.h" > > #include "isom.h" > > #include "libavcodec/get_bits.h" > > @@ -7051,58 +7052,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext > > *pb, MOVAtom atom) > > static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) > > { > > AVStream *st; > > -uint32_t buf; > > -AVDOVIDecoderConfigurationRecord *dovi; > > -size_t dovi_size; > > +uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; > > int ret; > > +int64_t read_size = atom.size; > > > > if (c->fc->nb_streams < 1) > > return 0; > > st = c->fc->streams[c->fc->nb_streams-1]; > > > > -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) > > -return AVERROR_INVALIDDATA; > > - > > -dovi = av_dovi_alloc(&dovi_size); > > -if (!dovi) > > -return AVERROR(ENOMEM); > > - > > -dovi->dv_version_major = avio_r8(pb); > > -dovi->dv_version_minor = avio_r8(pb); > > - > > -buf = avio_rb16(pb); > > -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits > > -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits > > -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit > > -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit > > -dovi->bl_present_flag = buf & 0x01;// 1 bit > > -if (atom.size >= 24) { // 4 + 4 + 4 * 4 > > -buf = avio_r8(pb); > > -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits > > -} else { > > -// 0 stands for None > > -// Dolby Vision V1.2.93 profiles and levels > > -dovi->dv_bl_signal_compatibility_id = 0; > > +// At most 24 bytes > > +if (read_size > ISOM_DVCC_DVVC_SIZE) { > > +read_size = ISOM_DVCC_DVVC_SIZE; > > } > > > > -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, > > - (uint8_t *)dovi, dovi_size); > > -if (ret < 0) { > > -av_free(dovi); > > +if ((ret = avio_read(pb, buf, read_size)) < 0) > > return ret; > > -} > > > > -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, > > profile: %d, level: %d, " > > - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: > > %d\n", > > - dovi->dv_version_major, dovi->dv_version_minor, > > - dovi->dv_profile, dovi->dv_level, > > - dovi->rpu_present_flag, > > - dovi->el_present_flag, > > - dovi->bl_present_flag, > > - dovi->dv_bl_signal_compatibility_id > > -); > > +read_size = ret; > > I prefer to check ret ! = read_size before like below: > if ((ret = avio_read(pb, buf, read_size)) != read_size) > return ret < 0 ? ret : AVERROR(EIO); Agreed. Will fix it. > > > > -return 0; > > +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); > > } > > > > static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom) > > -- > > 2.34.1 > > > > ___ > > 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". > > -- > Thanks, > Limin Wang > ___ > 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". ___ 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".
[FFmpeg-devel] [PATCH v10 0/5] Add support for Matroska BlockAdditionMapping elements
This patch set adds support for reading/writing the Matroska BlockAdditionMapping elements, as well as for reading/writing dvcC/dvvC blocks in Matroska. Created utility functions to read/write Dolby Vision boxes for ISOM. This was done to avoid duplicating the code, as the Matroska blocks and MOV boxes follow the same specification, defined by Dolby. Refactored the reading/writing in mov/movenc to use the new dovi_isom functions. v9: https://ffmpeg.org/pipermail/ffmpeg-devel/2021-December/288896.html Changes since v9: - mov: Fixed size validation for reading into temporary buffer. As suggested here: https://ffmpeg.org/pipermail/ffmpeg-devel/2021-December/289087.html - mov: Removed the unnecessary padding for the temporary buffer. Because avio_read respects the requested size. - matroskaenc: Changed mkv_write_dovi return type to void, as it is infallible. quietvoid (5): avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc fate/matroska: Add tests for reading/writing BlockAdditionMapping elements libavformat/Makefile | 4 +- libavformat/dovi_isom.c | 118 ++ libavformat/dovi_isom.h | 35 +++ libavformat/matroska.h | 9 + libavformat/matroskadec.c| 58 - libavformat/matroskaenc.c| 37 +++ libavformat/mov.c| 52 + libavformat/movenc.c | 24 +- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 11 files changed, 518 insertions(+), 64 deletions(-) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v10 1/5] avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing
Both parse/write implementations are based on mov/movenc. This only adds support for the "Dolby Vision configuration box". Other configuration boxes, such as "Dolby Vision enhancement layer configuration box" are not supported. The new functions will be used to implement parsing/writing the DOVI config for Matroska, as well as to refactor both mov/movenc to use dovi_isom functions. Signed-off-by: quietvoid --- libavformat/dovi_isom.c | 118 libavformat/dovi_isom.h | 35 2 files changed, 153 insertions(+) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..262d7e37ba --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,118 @@ +/* + * DOVI ISO Media common code + * + * Copyright (c) 2020 Vacing Fang + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "libavcodec/put_bits.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id); + +return 0; +} + +void ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; + +init_put_bits(&pb, out, ISOM_DVCC_DVVC_SIZE); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ + +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
[FFmpeg-devel] [PATCH v10 2/5] avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements
Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data. The configuration block is written when muxing into Matroska, if DOVI side data is present for the track. Most of the Matroska element parsing is based on Plex's FFmpeg source code. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 9 ++ libavformat/matroskadec.c | 58 +-- libavformat/matroskaenc.c | 37 + 4 files changed, 104 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index 2b5caf9d33..bd12562a24 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -314,11 +314,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..16491aae22 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB @@ -385,4 +392,6 @@ extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_P int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); +#define DVCC_DVVC_BLOCK_TYPE_NAME "Dolby Vision configuration" + #endif /* AVFORMAT_MATROSKA_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index a4bbbe954e..6ce553205d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -53,6 +53,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "internal.h" #include "isom.h" #include "matroska.h" @@ -239,6 +240,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +277,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +428,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +579,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_
[FFmpeg-devel] [PATCH v10 4/5] avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc
Improves code legibility by not using bit shifts. Also avoids duplicating the dvcC/dvvC ISOM box writing code. Signed-off-by: quietvoid --- libavformat/movenc.c | 24 +++- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 0f912dd012..f1fe43a79f 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -27,6 +27,7 @@ #include "movenc.h" #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "avio.h" #include "isom.h" @@ -1911,6 +1912,8 @@ static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMa static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi) { +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; + avio_wb32(pb, 32); /* size = 8 + 24 */ if (dovi->dv_profile > 10) ffio_wfourcc(pb, "dvwC"); @@ -1918,23 +1921,10 @@ static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDe ffio_wfourcc(pb, "dvvC"); else ffio_wfourcc(pb, "dvcC"); -avio_w8(pb, dovi->dv_version_major); -avio_w8(pb, dovi->dv_version_minor); -avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) | - (dovi->rpu_present_flag << 2) | (dovi->el_present_flag << 1) | - dovi->bl_present_flag); -avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0); - -ffio_fill(pb, 0, 4 * 4); /* reserved */ -av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? "dvvC" : "dvcC"), - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); + +ff_isom_put_dvcc_dvvc(s, buf, dovi); +avio_write(pb, buf, sizeof(buf)); + return 32; /* 8 + 24 */ } -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v10 3/5] avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc
To avoid duplicating code. The implementation in dovi_isom is identical. Signed-off-by: quietvoid --- libavformat/mov.c | 52 --- 1 file changed, 9 insertions(+), 43 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 9ebfa0bcc7..e3c80c399c 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -55,6 +55,7 @@ #include "avformat.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "isom.h" #include "libavcodec/get_bits.h" @@ -7056,58 +7057,23 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > ISOM_DVCC_DVVC_SIZE) { +read_size = ISOM_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); -return ret; -} +if ((ret = avio_read(pb, buf, read_size)) != read_size) +return ret < 0 ? ret : AVERROR(EIO); -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); - -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom) -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v10 5/5] fate/matroska: Add tests for reading/writing BlockAdditionMapping elements
Tests the parsing and writing of AVDOVIDecoderConfigurationRecord, when it is present as a Dolby Vision configuration block addition mapping. Signed-off-by: quietvoid --- The required regression test file is available here: https://0x0.st/-hWK.mkv Should be moved to fate-suite/mkv/dovi-p5.mkv It is a blank frame encoded with x265. --- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 3 files changed, 245 insertions(+) create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak index e117a0f6a6..ec2a0607b2 100644 --- a/tests/fate/matroska.mak +++ b/tests/fate/matroska.mak @@ -138,6 +138,15 @@ FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL WEBVTT_DEMUXER \ += fate-webm-webvtt-remux fate-webm-webvtt-remux: CMD = transcode webvtt $(TARGET_SAMPLES)/sub/WebVTT_capability_tester.vtt webm "-map 0 -map 0 -map 0 -map 0 -c:s copy -disposition:0 original+descriptions+hearing_impaired -disposition:1 lyrics+default+metadata -disposition:2 comment+forced -disposition:3 karaoke+captions+dub" "-map 0:0 -map 0:1 -c copy" "" "-show_entries stream_disposition:stream=index,codec_name:packet=stream_index,pts:packet_side_data_list -show_data_hash CRC32" +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, MATROSKA_DEMUXER) += fate-matroska-dovi-config-profile5 +fate-matroska-dovi-config-profile5: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mkv/dovi-p5.mkv + +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ +MOV_DEMUXER MATROSKA_MUXER \ +FRAMECRC_MUXER) \ + += fate-matroska-dovi-write-config +fate-matroska-dovi-write-config: CMD = transcode mov $(TARGET_SAMPLES)/hevc/dv84.mov matroska "-c:v copy" "-map 0 -c copy" "" "-show_entries stream_side_data_list -select_streams v -v 0" + FATE_SAMPLES_AVCONV += $(FATE_MATROSKA-yes) FATE_SAMPLES_FFPROBE += $(FATE_MATROSKA_FFPROBE-yes) FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MATROSKA_FFMPEG_FFPROBE-yes) diff --git a/tests/ref/fate/matroska-dovi-config-profile5 b/tests/ref/fate/matroska-dovi-config-profile5 new file mode 100644 index 00..a27976b71a --- /dev/null +++ b/tests/ref/fate/matroska-dovi-config-profile5 @@ -0,0 +1,13 @@ +[STREAM] +[SIDE_DATA] +side_data_type=DOVI configuration record +dv_version_major=1 +dv_version_minor=0 +dv_profile=5 +dv_level=4 +rpu_present_flag=1 +el_present_flag=0 +bl_present_flag=1 +dv_bl_signal_compatibility_id=0 +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/matroska-dovi-write-config b/tests/ref/fate/matroska-dovi-write-config new file mode 100644 index 00..a253db9f00 --- /dev/null +++ b/tests/ref/fate/matroska-dovi-write-config @@ -0,0 +1,223 @@ +47d2c151ff02720fff7bd37b3028097e *tests/data/fate/matroska-dovi-write-config.matroska +3618445 tests/data/fate/matroska-dovi-write-config.matroska +#extradata 0: 551, 0xa18acf66 +#tb 0: 1/1000 +#media_type 0: video +#codec_id 0: hevc +#dimensions 0: 1920x1080 +#sar 0: 0/1 +#tb 1: 1/1000 +#media_type 1: audio +#codec_id 1: ac3 +#sample_rate 1: 44100 +#channel_layout 1: 3 +#channel_layout_name 1: stereo +0,-67, 0, 33,63375, 0xc76606ab, S=1,8 +0,-34,133, 33,46706, 0x0e08a7e5, F=0x0 +0, 0, 73, 33,29766, 0x753c031a, F=0x0 +1, 0, 0, 34, 834, 0x6740ac04 +1, 35, 35, 34, 836, 0xe29a9a24 +0, 39, 39, 33,19409, 0x4b948b6c, F=0x0 +1, 70, 70, 34, 836, 0xf7329e5f +0, 73,106, 33,21086, 0x1b9412ce, F=0x0 +1,105,105, 34, 836, 0x9622a243 +0,106,273, 33,62043, 0xc2356b56, F=0x0 +0,133,206, 33,36175, 0x0a7df38c, F=0x0 +1,140,140, 34, 836, 0xb2d497c5 +0,173,173, 33,16028, 0xa57fcbe9, F=0x0 +1,174,174, 34, 836, 0x17c8980e +0,206,239, 33,15428, 0x9a91f357, F=0x0 +1,209,209, 34, 836, 0xfe288a7d +0,239,406, 33,66072, 0xa542b6d7, F=0x0 +1,244,244, 34, 836, 0x539e82b1 +0,273,339, 33,34985, 0xbfd8ff45, F=0x0 +1,279,279, 34, 836, 0x166291cb +0,306,306, 33,16036, 0xfc39c6ea, F=0x0 +1,314,314, 34, 836, 0x30127c33 +0,3
Re: [FFmpeg-devel] [PATCH] fate: Add regression tests for AVDOVIDecoderConfigurationRecord side data
On Fri, Nov 26, 2021 at 12:06 PM quietvoid wrote: > > Signed-off-by: quietvoid > --- > Files are available here: > https://drive.google.com/drive/folders/1NDhtSoJ-mP5Yi62V6j1wjjPJNq84nP3J > > They're all blank frames encoded with x265, remuxed with FFmpeg > after the mov box is added by dlb_mp4base. > > Let me know if the hosting is not appropriate. > I thought it was better than zipping everything. > --- > tests/fate/mov.mak | 17 > tests/fate/mpegts.mak | 2 + > tests/ref/fate/mov-dovi-config-profile5| 13 ++ > tests/ref/fate/mov-dovi-config-profile7| 15 +++ > tests/ref/fate/mov-dovi-config-profile81 | 13 ++ > tests/ref/fate/mov-dovi-config-profile84 | 22 ++ > tests/ref/fate/mov-dovi-write-config | 49 ++ > tests/ref/fate/mpegts-dovi-config-profile7 | 15 +++ > 8 files changed, 146 insertions(+) > create mode 100644 tests/ref/fate/mov-dovi-config-profile5 > create mode 100644 tests/ref/fate/mov-dovi-config-profile7 > create mode 100644 tests/ref/fate/mov-dovi-config-profile81 > create mode 100644 tests/ref/fate/mov-dovi-config-profile84 > create mode 100644 tests/ref/fate/mov-dovi-write-config > create mode 100644 tests/ref/fate/mpegts-dovi-config-profile7 > > diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak > index 5ca992e181..8ef7cb1edf 100644 > --- a/tests/fate/mov.mak > +++ b/tests/fate/mov.mak > @@ -145,6 +145,23 @@ FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL > PIPE_PROTOCOL \ >+= fate-mov-mp4-disposition-mpegts-remux > fate-mov-mp4-disposition-mpegts-remux: CMD = transcode mpegts > $(TARGET_SAMPLES)/mpegts/pmtchange.ts mp4 "-map 0:1 -map 0:2 -c copy > -disposition:a:0 +hearing_impaired" "-map 0 -c copy" "" "-of json > -show_entries stream_disposition:stream=index" > > +# Tests for AVDOVIDecoderConfigurationRecord parsing in mov > +FATE_MOV_FFMPEG_FFPROBE-$(call DEMDEC, MOV) \ > + += fate-mov-dovi-config-profile5 \ > + fate-mov-dovi-config-profile7 \ > + fate-mov-dovi-config-profile81 \ > + fate-mov-dovi-config-profile84 > +fate-mov-dovi-config-profile5: CMD = run ffprobe$(PROGSSUF)$(EXESUF) > -show_entries stream_side_data_list -select_streams v -v 0 > $(TARGET_SAMPLES)/mov/dovi-p5.mp4 > +fate-mov-dovi-config-profile7: CMD = run ffprobe$(PROGSSUF)$(EXESUF) > -show_entries stream_side_data_list -select_streams v -v 0 > $(TARGET_SAMPLES)/mov/dovi-p7.mp4 > +fate-mov-dovi-config-profile81: CMD = run ffprobe$(PROGSSUF)$(EXESUF) > -show_entries stream_side_data_list -select_streams v -v 0 > $(TARGET_SAMPLES)/mov/dovi-p81.mp4 > +fate-mov-dovi-config-profile84: CMD = run ffprobe$(PROGSSUF)$(EXESUF) > -show_entries stream_side_data_list -select_streams v -v 0 > $(TARGET_SAMPLES)/hevc/dv84.mov > + > +FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ > + MPEGTS_DEMUXER MOV_DEMUXER \ > + MP4_MUXER FRAMECRC_MUXER) \ > + += fate-mov-dovi-write-config > +fate-mov-dovi-write-config: CMD = transcode mpegts > $(TARGET_SAMPLES)/mpegts/dovi-p7.ts mp4 "-map 0:0 -map 0:1 -c copy -strict > unofficial" "-map 0 -c copy" "" "-show_entries stream_side_data_list > -select_streams v -v 0" > + > FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MOV_FFMPEG_FFPROBE-yes) > > fate-mov: $(FATE_MOV) $(FATE_MOV_FFPROBE) $(FATE_MOV_FASTSTART) > $(FATE_MOV_FFMPEG_FFPROBE-yes) > diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak > index bbcbfc47b2..1ee44ff2a0 100644 > --- a/tests/fate/mpegts.mak > +++ b/tests/fate/mpegts.mak > @@ -19,6 +19,8 @@ FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += > fate-mpegts-probe-pmt-merge > fate-mpegts-probe-pmt-merge: SRC = $(TARGET_SAMPLES)/mpegts/pmtchange.ts > fate-mpegts-probe-pmt-merge: CMD = run $(PROBE_CODEC_NAME_COMMAND) > -merge_pmt_versions 1 -i "$(SRC)" > > +FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-dovi-config-profile7 > +fate-mpegts-dovi-config-profile7: CMD = run ffprobe$(PROGSSUF)$(EXESUF) > -show_entries stream_side_data_list -select_streams v -v 0 > $(TARGET_SAMPLES)/mpegts/dovi-p7.ts > > FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROBE-yes) > > diff --git a/tests/ref/fate/mov-dovi-config-profile5 > b/tests/ref/fate/mov-dovi-config-profile5 > new file mode 100644 > index 00..a27976b71a > --- /dev/null > +++ b/tests/ref/fate/mov-dovi-config-profile5 > @@ -0,0 +1,13 @@ > +[STREA
[FFmpeg-devel] [PATCH v11 0/5] Add support for Matroska BlockAdditionMapping elements
This patch set adds support for reading/writing the Matroska BlockAdditionMapping elements, as well as for reading/writing dvcC/dvvC blocks in Matroska. Created utility functions to read/write Dolby Vision boxes for ISOM. This was done to avoid duplicating the code, as the Matroska blocks and MOV boxes follow the same specification, defined by Dolby. Refactored the reading/writing in mov/movenc to use the new dovi_isom functions. v10: https://ffmpeg.org/pipermail/ffmpeg-devel/2021-December/289645.html Changes since v10: - dovi_isom: Limited written values to fit into the amount of bits. - matroskaenc: Corrected mkv_write_dovi to only allow profiles that are valid for dvcC/dvvC configurations. - mov: Improved code to be more concise. quietvoid (5): avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc fate/matroska: Add tests for reading/writing BlockAdditionMapping elements libavformat/Makefile | 4 +- libavformat/dovi_isom.c | 118 ++ libavformat/dovi_isom.h | 35 +++ libavformat/matroska.h | 9 + libavformat/matroskadec.c| 58 - libavformat/matroskaenc.c| 37 +++ libavformat/mov.c| 50 + libavformat/movenc.c | 24 +- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 11 files changed, 516 insertions(+), 64 deletions(-) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v11 1/5] avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing
Both parse/write implementations are based on mov/movenc. This only adds support for the "Dolby Vision configuration box". Other configuration boxes, such as "Dolby Vision enhancement layer configuration box" are not supported. The new functions will be used to implement parsing/writing the DOVI config for Matroska, as well as to refactor both mov/movenc to use dovi_isom functions. Signed-off-by: quietvoid --- libavformat/dovi_isom.c | 118 libavformat/dovi_isom.h | 35 2 files changed, 153 insertions(+) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..76681b9451 --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,118 @@ +/* + * DOVI ISO Media common code + * + * Copyright (c) 2020 Vacing Fang + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "libavcodec/put_bits.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id); + +return 0; +} + +void ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; + +init_put_bits(&pb, out, ISOM_DVCC_DVVC_SIZE); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile & 0x7f); +put_bits(&pb, 6, dovi->dv_level & 0x3f); +put_bits(&pb, 1, !!dovi->rpu_present_flag); +put_bits(&pb, 1, !!dovi->el_present_flag); +put_bits(&pb, 1, !!dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id & 0x0f); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ + +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d,
[FFmpeg-devel] [PATCH v11 2/5] avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements
Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data. The configuration block is written when muxing into Matroska, if DOVI side data is present for the track. Most of the Matroska element parsing is based on Plex's FFmpeg source code. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 9 ++ libavformat/matroskadec.c | 58 +-- libavformat/matroskaenc.c | 37 + 4 files changed, 104 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index e31b248ac0..4464c2b049 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -316,11 +316,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..16491aae22 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB @@ -385,4 +392,6 @@ extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_P int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); +#define DVCC_DVVC_BLOCK_TYPE_NAME "Dolby Vision configuration" + #endif /* AVFORMAT_MATROSKA_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index a4bbbe954e..6ce553205d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -53,6 +53,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "internal.h" #include "isom.h" #include "matroska.h" @@ -239,6 +240,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +277,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +428,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +579,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_
[FFmpeg-devel] [PATCH v11 3/5] avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc
To avoid duplicating code. The implementation in dovi_isom is identical. Signed-off-by: quietvoid --- libavformat/mov.c | 50 +++ 1 file changed, 7 insertions(+), 43 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 351ecde770..ad5ab6b491 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -55,6 +55,7 @@ #include "avformat.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "isom.h" #include "libavcodec/get_bits.h" @@ -7062,58 +7063,21 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; -} +// At most 24 bytes +read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE); -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ffio_read_size(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); - -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom) -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v11 4/5] avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc
Improves code legibility by not using bit shifts. Also avoids duplicating the dvcC/dvvC ISOM box writing code. Signed-off-by: quietvoid --- libavformat/movenc.c | 24 +++- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 0f912dd012..f1fe43a79f 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -27,6 +27,7 @@ #include "movenc.h" #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "avio.h" #include "isom.h" @@ -1911,6 +1912,8 @@ static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMa static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi) { +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; + avio_wb32(pb, 32); /* size = 8 + 24 */ if (dovi->dv_profile > 10) ffio_wfourcc(pb, "dvwC"); @@ -1918,23 +1921,10 @@ static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDe ffio_wfourcc(pb, "dvvC"); else ffio_wfourcc(pb, "dvcC"); -avio_w8(pb, dovi->dv_version_major); -avio_w8(pb, dovi->dv_version_minor); -avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) | - (dovi->rpu_present_flag << 2) | (dovi->el_present_flag << 1) | - dovi->bl_present_flag); -avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0); - -ffio_fill(pb, 0, 4 * 4); /* reserved */ -av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? "dvvC" : "dvcC"), - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); + +ff_isom_put_dvcc_dvvc(s, buf, dovi); +avio_write(pb, buf, sizeof(buf)); + return 32; /* 8 + 24 */ } -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v11 5/5] fate/matroska: Add tests for reading/writing BlockAdditionMapping elements
Tests the parsing and writing of AVDOVIDecoderConfigurationRecord, when it is present as a Dolby Vision configuration block addition mapping. Signed-off-by: quietvoid --- The required regression test file is available here: https://0x0.st/-hWK.mkv Should be moved to fate-suite/mkv/dovi-p5.mkv It is a blank frame encoded with x265. --- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 3 files changed, 245 insertions(+) create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak index e117a0f6a6..ec2a0607b2 100644 --- a/tests/fate/matroska.mak +++ b/tests/fate/matroska.mak @@ -138,6 +138,15 @@ FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL WEBVTT_DEMUXER \ += fate-webm-webvtt-remux fate-webm-webvtt-remux: CMD = transcode webvtt $(TARGET_SAMPLES)/sub/WebVTT_capability_tester.vtt webm "-map 0 -map 0 -map 0 -map 0 -c:s copy -disposition:0 original+descriptions+hearing_impaired -disposition:1 lyrics+default+metadata -disposition:2 comment+forced -disposition:3 karaoke+captions+dub" "-map 0:0 -map 0:1 -c copy" "" "-show_entries stream_disposition:stream=index,codec_name:packet=stream_index,pts:packet_side_data_list -show_data_hash CRC32" +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, MATROSKA_DEMUXER) += fate-matroska-dovi-config-profile5 +fate-matroska-dovi-config-profile5: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mkv/dovi-p5.mkv + +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ +MOV_DEMUXER MATROSKA_MUXER \ +FRAMECRC_MUXER) \ + += fate-matroska-dovi-write-config +fate-matroska-dovi-write-config: CMD = transcode mov $(TARGET_SAMPLES)/hevc/dv84.mov matroska "-c:v copy" "-map 0 -c copy" "" "-show_entries stream_side_data_list -select_streams v -v 0" + FATE_SAMPLES_AVCONV += $(FATE_MATROSKA-yes) FATE_SAMPLES_FFPROBE += $(FATE_MATROSKA_FFPROBE-yes) FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MATROSKA_FFMPEG_FFPROBE-yes) diff --git a/tests/ref/fate/matroska-dovi-config-profile5 b/tests/ref/fate/matroska-dovi-config-profile5 new file mode 100644 index 00..a27976b71a --- /dev/null +++ b/tests/ref/fate/matroska-dovi-config-profile5 @@ -0,0 +1,13 @@ +[STREAM] +[SIDE_DATA] +side_data_type=DOVI configuration record +dv_version_major=1 +dv_version_minor=0 +dv_profile=5 +dv_level=4 +rpu_present_flag=1 +el_present_flag=0 +bl_present_flag=1 +dv_bl_signal_compatibility_id=0 +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/matroska-dovi-write-config b/tests/ref/fate/matroska-dovi-write-config new file mode 100644 index 00..a253db9f00 --- /dev/null +++ b/tests/ref/fate/matroska-dovi-write-config @@ -0,0 +1,223 @@ +47d2c151ff02720fff7bd37b3028097e *tests/data/fate/matroska-dovi-write-config.matroska +3618445 tests/data/fate/matroska-dovi-write-config.matroska +#extradata 0: 551, 0xa18acf66 +#tb 0: 1/1000 +#media_type 0: video +#codec_id 0: hevc +#dimensions 0: 1920x1080 +#sar 0: 0/1 +#tb 1: 1/1000 +#media_type 1: audio +#codec_id 1: ac3 +#sample_rate 1: 44100 +#channel_layout 1: 3 +#channel_layout_name 1: stereo +0,-67, 0, 33,63375, 0xc76606ab, S=1,8 +0,-34,133, 33,46706, 0x0e08a7e5, F=0x0 +0, 0, 73, 33,29766, 0x753c031a, F=0x0 +1, 0, 0, 34, 834, 0x6740ac04 +1, 35, 35, 34, 836, 0xe29a9a24 +0, 39, 39, 33,19409, 0x4b948b6c, F=0x0 +1, 70, 70, 34, 836, 0xf7329e5f +0, 73,106, 33,21086, 0x1b9412ce, F=0x0 +1,105,105, 34, 836, 0x9622a243 +0,106,273, 33,62043, 0xc2356b56, F=0x0 +0,133,206, 33,36175, 0x0a7df38c, F=0x0 +1,140,140, 34, 836, 0xb2d497c5 +0,173,173, 33,16028, 0xa57fcbe9, F=0x0 +1,174,174, 34, 836, 0x17c8980e +0,206,239, 33,15428, 0x9a91f357, F=0x0 +1,209,209, 34, 836, 0xfe288a7d +0,239,406, 33,66072, 0xa542b6d7, F=0x0 +1,244,244, 34, 836, 0x539e82b1 +0,273,339, 33,34985, 0xbfd8ff45, F=0x0 +1,279,279, 34, 836, 0x166291cb +0,306,306, 33,16036, 0xfc39c6ea, F=0x0 +1,314,314, 34, 836, 0x30127c33 +0,3
Re: [FFmpeg-devel] [PATCH v10 1/5] avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing
On Fri, Dec 31, 2021 at 9:16 PM Andreas Rheinhardt wrote: > > quietvoid: > > Both parse/write implementations are based on mov/movenc. > > > > This only adds support for the "Dolby Vision configuration box". > > Other configuration boxes, such as > > "Dolby Vision enhancement layer configuration box" are not supported. > > > > The new functions will be used to implement parsing/writing the DOVI config > > for Matroska, as well as to refactor both mov/movenc to use dovi_isom > > functions. > > > > Signed-off-by: quietvoid > > --- > > libavformat/dovi_isom.c | 118 > > libavformat/dovi_isom.h | 35 > > 2 files changed, 153 insertions(+) > > create mode 100644 libavformat/dovi_isom.c > > create mode 100644 libavformat/dovi_isom.h > > > > diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c > > new file mode 100644 > > index 00..262d7e37ba > > --- /dev/null > > +++ b/libavformat/dovi_isom.c > > @@ -0,0 +1,118 @@ > > +/* > > + * DOVI ISO Media common code > > + * > > + * Copyright (c) 2020 Vacing Fang > > + * Copyright (c) 2021 quietvoid > > + * > > + * 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 "libavutil/dovi_meta.h" > > + > > +#include "libavcodec/put_bits.h" > > + > > +#include "avformat.h" > > +#include "dovi_isom.h" > > + > > +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const > > uint8_t *buf_ptr, uint64_t size) > > +{ > > +uint32_t buf; > > +AVDOVIDecoderConfigurationRecord *dovi; > > +size_t dovi_size; > > +int ret; > > + > > +if (size > (1 << 30) || size < 4) > > +return AVERROR_INVALIDDATA; > > + > > +dovi = av_dovi_alloc(&dovi_size); > > +if (!dovi) > > +return AVERROR(ENOMEM); > > + > > +dovi->dv_version_major = *buf_ptr++;// 8 bits > > +dovi->dv_version_minor = *buf_ptr++;// 8 bits > > + > > +buf = *buf_ptr++ << 8; > > +buf |= *buf_ptr++; > > + > > +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits > > +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits > > +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit > > +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit > > +dovi->bl_present_flag = buf & 0x01;// 1 bit > > + > > +// Has enough remaining data > > +if (size >= 5) { > > +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; > > // 4 bits > > +} else { > > +// 0 stands for None > > +// Dolby Vision V1.2.93 profiles and levels > > +dovi->dv_bl_signal_compatibility_id = 0; > > +} > > + > > +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, > > + (uint8_t *)dovi, dovi_size); > > +if (ret < 0) { > > +av_free(dovi); > > +return ret; > > +} > > + > > +av_log(s, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, > > profile: %d, level: %d, " > > + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: > > %d\n", > > + dovi->dv_version_major, dovi->dv_version_minor, > > + dovi->dv_profile, dovi->dv_level, > > + dovi->rpu_present_flag, > > + dovi->el_present_flag, > > + dovi->bl_present_flag, > > + dovi->dv_b
[FFmpeg-devel] [PATCH v2] fate: Add regression tests for AVDOVIDecoderConfigurationRecord side data
Signed-off-by: quietvoid --- Files are available here (in a zip): https://0x0.st/osvi.zip Alternatively: https://drive.google.com/drive/folders/1NDhtSoJ-mP5Yi62V6j1wjjPJNq84nP3J They're all blank frames encoded with x265, remuxed with FFmpeg after the mov box is added by dlb_mp4base. MP4 files should be moved to fate-suite/mov. MPEGTS file into fate-suite/mpegts. --- tests/fate/mov.mak | 16 +++ tests/fate/mpegts.mak | 2 + tests/ref/fate/mov-dovi-config-profile5| 13 ++ tests/ref/fate/mov-dovi-config-profile7| 15 +++ tests/ref/fate/mov-dovi-config-profile81 | 13 ++ tests/ref/fate/mov-dovi-config-profile84 | 22 ++ tests/ref/fate/mov-dovi-write-config | 49 ++ tests/ref/fate/mpegts-dovi-config-profile7 | 15 +++ 8 files changed, 145 insertions(+) create mode 100644 tests/ref/fate/mov-dovi-config-profile5 create mode 100644 tests/ref/fate/mov-dovi-config-profile7 create mode 100644 tests/ref/fate/mov-dovi-config-profile81 create mode 100644 tests/ref/fate/mov-dovi-config-profile84 create mode 100644 tests/ref/fate/mov-dovi-write-config create mode 100644 tests/ref/fate/mpegts-dovi-config-profile7 diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index e956380909..26f62bf156 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -30,6 +30,10 @@ FATE_MOV_FFPROBE = fate-mov-neg-firstpts-discard \ fate-mov-guess-delay-3 \ fate-mov-mp4-with-mov-in24-ver \ fate-mov-mp4-extended-atom \ + fate-mov-dovi-config-profile5 \ + fate-mov-dovi-config-profile7 \ + fate-mov-dovi-config-profile81 \ + fate-mov-dovi-config-profile84 \ FATE_MOV_FASTSTART = fate-mov-faststart-4gb-overflow \ @@ -126,6 +130,12 @@ fate-mov-mp4-with-mov-in24-ver: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entr fate-mov-mp4-extended-atom: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_packets -print_format compact -select_streams v $(TARGET_SAMPLES)/mov/extended_atom_size_probe +# ffprobe tests for AVDOVIDecoderConfigurationRecord parsing in mov +fate-mov-dovi-config-profile5: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mov/dovi-p5.mp4 +fate-mov-dovi-config-profile7: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mov/dovi-p7.mp4 +fate-mov-dovi-config-profile81: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mov/dovi-p81.mp4 +fate-mov-dovi-config-profile84: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/hevc/dv84.mov + FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL MOV_DEMUXER MJPEG_DECODER \ SCALE_FILTER PNG_ENCODER PNG_DECODER \ MP4_MUXER FRAMECRC_MUXER PIPE_PROTOCOL) \ @@ -145,6 +155,12 @@ FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ += fate-mov-mp4-disposition-mpegts-remux fate-mov-mp4-disposition-mpegts-remux: CMD = transcode mpegts $(TARGET_SAMPLES)/mpegts/pmtchange.ts mp4 "-map 0:1 -map 0:2 -c copy -disposition:a:0 +hearing_impaired" "-map 0 -c copy" "" "-of json -show_entries stream_disposition:stream=index" +FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ + MPEGTS_DEMUXER MOV_DEMUXER \ + MP4_MUXER FRAMECRC_MUXER) \ + += fate-mov-dovi-write-config +fate-mov-dovi-write-config: CMD = transcode mpegts $(TARGET_SAMPLES)/mpegts/dovi-p7.ts mp4 "-map 0:0 -map 0:1 -c copy -strict unofficial" "-map 0 -c copy" "" "-show_entries stream_side_data_list -select_streams v -v 0" + FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MOV_FFMPEG_FFPROBE-yes) fate-mov: $(FATE_MOV) $(FATE_MOV_FFPROBE) $(FATE_MOV_FASTSTART) $(FATE_MOV_FFMPEG_FFPROBE-yes) diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak index bbcbfc47b2..1ee44ff2a0 100644 --- a/tests/fate/mpegts.mak +++ b/tests/fate/mpegts.mak @@ -19,6 +19,8 @@ FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-probe-pmt-merge fate-mpegts-probe-pmt-merge: SRC = $(TARGET_SAMPLES)/mpegts/pmtchange.ts fate-mpegts-probe-pmt-merge: CMD = run $(PROBE_CODEC_NAME_COMMAND) -merge_pmt_versions 1 -i "$(SRC)" +FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-dovi-config-profile7 +fate-mpegts-dovi-config-profile7: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mpegts/dovi-p7.ts FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROB
[FFmpeg-devel] [PATCH v12 0/5] Add support for Matroska BlockAdditionMapping elements
This patch set adds support for reading/writing the Matroska BlockAdditionMapping elements, as well as for reading/writing dvcC/dvvC blocks in Matroska. Created utility functions to read/write Dolby Vision boxes for ISOM. This was done to avoid duplicating the code, as the Matroska blocks and MOV boxes follow the same specification, defined by Dolby. Refactored the reading/writing in mov/movenc to use the new dovi_isom functions. v11: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-January/290611.html Changes since v11: - mov/movenc: Added dovi_isom linked object in Makefile for MOV DEMUXER/MUXER. - fate/matroska: Fixed ffprobe test set name and requirements. As suggested here: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-January/290621.html quietvoid (5): avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc fate/matroska: Add tests for reading/writing BlockAdditionMapping elements libavformat/Makefile | 9 +- libavformat/dovi_isom.c | 118 ++ libavformat/dovi_isom.h | 35 +++ libavformat/matroska.h | 9 + libavformat/matroskadec.c| 58 - libavformat/matroskaenc.c| 37 +++ libavformat/mov.c| 50 + libavformat/movenc.c | 24 +- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 11 files changed, 519 insertions(+), 66 deletions(-) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v12 1/5] avformat/dovi_isom: Implement Dolby Vision configuration parsing/writing
Both parse/write implementations are based on mov/movenc. This only adds support for the "Dolby Vision configuration box". Other configuration boxes, such as "Dolby Vision enhancement layer configuration box" are not supported. The new functions will be used to implement parsing/writing the DOVI config for Matroska, as well as to refactor both mov/movenc to use dovi_isom functions. Signed-off-by: quietvoid --- libavformat/dovi_isom.c | 118 libavformat/dovi_isom.h | 35 2 files changed, 153 insertions(+) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..76681b9451 --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,118 @@ +/* + * DOVI ISO Media common code + * + * Copyright (c) 2020 Vacing Fang + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "libavcodec/put_bits.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1 << 30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id); + +return 0; +} + +void ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE], + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; + +init_put_bits(&pb, out, ISOM_DVCC_DVVC_SIZE); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile & 0x7f); +put_bits(&pb, 6, dovi->dv_level & 0x3f); +put_bits(&pb, 1, !!dovi->rpu_present_flag); +put_bits(&pb, 1, !!dovi->el_present_flag); +put_bits(&pb, 1, !!dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id & 0x0f); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ + +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d,
[FFmpeg-devel] [PATCH v12 2/5] avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements
Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data. The configuration block is written when muxing into Matroska, if DOVI side data is present for the track. Most of the Matroska element parsing is based on Plex's FFmpeg source code. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h| 9 ++ libavformat/matroskadec.c | 58 +-- libavformat/matroskaenc.c | 37 + 4 files changed, 104 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index e31b248ac0..4464c2b049 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -316,11 +316,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..16491aae22 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB @@ -385,4 +392,6 @@ extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_P int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); +#define DVCC_DVVC_BLOCK_TYPE_NAME "Dolby Vision configuration" + #endif /* AVFORMAT_MATROSKA_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index a4bbbe954e..6ce553205d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -53,6 +53,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "internal.h" #include "isom.h" #include "matroska.h" @@ -239,6 +240,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +277,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +428,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +579,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_
[FFmpeg-devel] [PATCH v12 3/5] avformat/mov: Refactor mov_read_dvcc_dvvc to use ff_isom_parse_dvcc_dvvc
To avoid duplicating code. The implementation in dovi_isom is identical. Signed-off-by: quietvoid --- libavformat/Makefile | 2 +- libavformat/mov.c| 50 +++- 2 files changed, 8 insertions(+), 44 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index 4464c2b049..cd9810ba01 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -339,7 +339,7 @@ OBJS-$(CONFIG_MMF_MUXER) += mmf.o rawenc.o OBJS-$(CONFIG_MODS_DEMUXER) += mods.o OBJS-$(CONFIG_MOFLEX_DEMUXER)+= moflex.o OBJS-$(CONFIG_MOV_DEMUXER) += mov.o mov_chan.o mov_esds.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MOV_MUXER) += movenc.o av1.o avc.o hevc.o vpcc.o \ movenchint.o mov_chan.o rtp.o \ movenccenc.o movenc_ttml.o rawutils.o diff --git a/libavformat/mov.c b/libavformat/mov.c index 351ecde770..ad5ab6b491 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -55,6 +55,7 @@ #include "avformat.h" #include "internal.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "isom.h" #include "libavcodec/get_bits.h" @@ -7062,58 +7063,21 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; -} +// At most 24 bytes +read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE); -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ffio_read_size(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); - -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom) -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v12 4/5] avformat/movenc: Refactor mov_write_dvcc_dvvc_tag to use ff_isom_put_dvcc_dvvc
Improves code legibility by not using bit shifts. Also avoids duplicating the dvcC/dvvC ISOM box writing code. Signed-off-by: quietvoid --- libavformat/Makefile | 3 ++- libavformat/movenc.c | 24 +++- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index cd9810ba01..a9afb9c042 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -342,7 +342,8 @@ OBJS-$(CONFIG_MOV_DEMUXER) += mov.o mov_chan.o mov_esds.o \ qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MOV_MUXER) += movenc.o av1.o avc.o hevc.o vpcc.o \ movenchint.o mov_chan.o rtp.o \ -movenccenc.o movenc_ttml.o rawutils.o +movenccenc.o movenc_ttml.o rawutils.o \ +dovi_isom.o OBJS-$(CONFIG_MP2_MUXER) += rawenc.o OBJS-$(CONFIG_MP3_DEMUXER) += mp3dec.o replaygain.o OBJS-$(CONFIG_MP3_MUXER) += mp3enc.o rawenc.o id3v2enc.o diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 0f912dd012..f1fe43a79f 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -27,6 +27,7 @@ #include "movenc.h" #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "riff.h" #include "avio.h" #include "isom.h" @@ -1911,6 +1912,8 @@ static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMa static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi) { +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; + avio_wb32(pb, 32); /* size = 8 + 24 */ if (dovi->dv_profile > 10) ffio_wfourcc(pb, "dvwC"); @@ -1918,23 +1921,10 @@ static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDe ffio_wfourcc(pb, "dvvC"); else ffio_wfourcc(pb, "dvcC"); -avio_w8(pb, dovi->dv_version_major); -avio_w8(pb, dovi->dv_version_minor); -avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) | - (dovi->rpu_present_flag << 2) | (dovi->el_present_flag << 1) | - dovi->bl_present_flag); -avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0); - -ffio_fill(pb, 0, 4 * 4); /* reserved */ -av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? "dvvC" : "dvcC"), - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); + +ff_isom_put_dvcc_dvvc(s, buf, dovi); +avio_write(pb, buf, sizeof(buf)); + return 32; /* 8 + 24 */ } -- 2.34.1 ___ 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".
[FFmpeg-devel] [PATCH v12 5/5] fate/matroska: Add tests for reading/writing BlockAdditionMapping elements
Tests the parsing and writing of AVDOVIDecoderConfigurationRecord, when it is present as a Dolby Vision configuration block addition mapping. Signed-off-by: quietvoid --- The required regression test file is available here: https://0x0.st/-hWK.mkv Should be moved to fate-suite/mkv/dovi-p5.mkv It is a blank frame encoded with x265. --- tests/fate/matroska.mak | 9 + tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ tests/ref/fate/matroska-dovi-write-config| 223 +++ 3 files changed, 245 insertions(+) create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 create mode 100644 tests/ref/fate/matroska-dovi-write-config diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak index e117a0f6a6..5a86d0fc45 100644 --- a/tests/fate/matroska.mak +++ b/tests/fate/matroska.mak @@ -138,6 +138,15 @@ FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL WEBVTT_DEMUXER \ += fate-webm-webvtt-remux fate-webm-webvtt-remux: CMD = transcode webvtt $(TARGET_SAMPLES)/sub/WebVTT_capability_tester.vtt webm "-map 0 -map 0 -map 0 -map 0 -c:s copy -disposition:0 original+descriptions+hearing_impaired -disposition:1 lyrics+default+metadata -disposition:2 comment+forced -disposition:3 karaoke+captions+dub" "-map 0:0 -map 0:1 -c copy" "" "-show_entries stream_disposition:stream=index,codec_name:packet=stream_index,pts:packet_side_data_list -show_data_hash CRC32" +FATE_MATROSKA_FFPROBE-$(CONFIG_MATROSKA_DEMUXER) += fate-matroska-dovi-config-profile5 +fate-matroska-dovi-config-profile5: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mkv/dovi-p5.mkv + +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ +MOV_DEMUXER MATROSKA_DEMUXER \ +MATROSKA_MUXER FRAMECRC_MUXER) \ + += fate-matroska-dovi-write-config +fate-matroska-dovi-write-config: CMD = transcode mov $(TARGET_SAMPLES)/hevc/dv84.mov matroska "-c:v copy" "-map 0 -c copy" "" "-show_entries stream_side_data_list -select_streams v -v 0" + FATE_SAMPLES_AVCONV += $(FATE_MATROSKA-yes) FATE_SAMPLES_FFPROBE += $(FATE_MATROSKA_FFPROBE-yes) FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MATROSKA_FFMPEG_FFPROBE-yes) diff --git a/tests/ref/fate/matroska-dovi-config-profile5 b/tests/ref/fate/matroska-dovi-config-profile5 new file mode 100644 index 00..a27976b71a --- /dev/null +++ b/tests/ref/fate/matroska-dovi-config-profile5 @@ -0,0 +1,13 @@ +[STREAM] +[SIDE_DATA] +side_data_type=DOVI configuration record +dv_version_major=1 +dv_version_minor=0 +dv_profile=5 +dv_level=4 +rpu_present_flag=1 +el_present_flag=0 +bl_present_flag=1 +dv_bl_signal_compatibility_id=0 +[/SIDE_DATA] +[/STREAM] diff --git a/tests/ref/fate/matroska-dovi-write-config b/tests/ref/fate/matroska-dovi-write-config new file mode 100644 index 00..a253db9f00 --- /dev/null +++ b/tests/ref/fate/matroska-dovi-write-config @@ -0,0 +1,223 @@ +47d2c151ff02720fff7bd37b3028097e *tests/data/fate/matroska-dovi-write-config.matroska +3618445 tests/data/fate/matroska-dovi-write-config.matroska +#extradata 0: 551, 0xa18acf66 +#tb 0: 1/1000 +#media_type 0: video +#codec_id 0: hevc +#dimensions 0: 1920x1080 +#sar 0: 0/1 +#tb 1: 1/1000 +#media_type 1: audio +#codec_id 1: ac3 +#sample_rate 1: 44100 +#channel_layout 1: 3 +#channel_layout_name 1: stereo +0,-67, 0, 33,63375, 0xc76606ab, S=1,8 +0,-34,133, 33,46706, 0x0e08a7e5, F=0x0 +0, 0, 73, 33,29766, 0x753c031a, F=0x0 +1, 0, 0, 34, 834, 0x6740ac04 +1, 35, 35, 34, 836, 0xe29a9a24 +0, 39, 39, 33,19409, 0x4b948b6c, F=0x0 +1, 70, 70, 34, 836, 0xf7329e5f +0, 73,106, 33,21086, 0x1b9412ce, F=0x0 +1,105,105, 34, 836, 0x9622a243 +0,106,273, 33,62043, 0xc2356b56, F=0x0 +0,133,206, 33,36175, 0x0a7df38c, F=0x0 +1,140,140, 34, 836, 0xb2d497c5 +0,173,173, 33,16028, 0xa57fcbe9, F=0x0 +1,174,174, 34, 836, 0x17c8980e +0,206,239, 33,15428, 0x9a91f357, F=0x0 +1,209,209, 34, 836, 0xfe288a7d +0,239,406, 33,66072, 0xa542b6d7, F=0x0 +1,244,244, 34, 836, 0x539e82b1 +0,273,339, 33,34985, 0xbfd8ff45, F=0x0 +1,279,279, 34, 836, 0x166291cb +0,306,306, 33,16036, 0xfc39c6ea, F=0x0 +1,314,314, 34, 836, 0x30127c33 +0,3
Re: [FFmpeg-devel] [PATCH v11 5/5] fate/matroska: Add tests for reading/writing BlockAdditionMapping elements
On Sat, Jan 1, 2022 at 2:57 AM Andreas Rheinhardt wrote: > > quietvoid: > > Tests the parsing and writing of AVDOVIDecoderConfigurationRecord, > > when it is present as a Dolby Vision configuration block addition mapping. > > > > Signed-off-by: quietvoid > > --- > > The required regression test file is available here: https://0x0.st/-hWK.mkv > > Should be moved to fate-suite/mkv/dovi-p5.mkv > > > > It is a blank frame encoded with x265. > > --- > > tests/fate/matroska.mak | 9 + > > tests/ref/fate/matroska-dovi-config-profile5 | 13 ++ > > tests/ref/fate/matroska-dovi-write-config| 223 +++ > > 3 files changed, 245 insertions(+) > > create mode 100644 tests/ref/fate/matroska-dovi-config-profile5 > > create mode 100644 tests/ref/fate/matroska-dovi-write-config > > > > diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak > > index e117a0f6a6..ec2a0607b2 100644 > > --- a/tests/fate/matroska.mak > > +++ b/tests/fate/matroska.mak > > @@ -138,6 +138,15 @@ FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, > > FILE_PROTOCOL WEBVTT_DEMUXER \ > > += fate-webm-webvtt-remux > > fate-webm-webvtt-remux: CMD = transcode webvtt > > $(TARGET_SAMPLES)/sub/WebVTT_capability_tester.vtt webm "-map 0 -map 0 -map > > 0 -map 0 -c:s copy -disposition:0 original+descriptions+hearing_impaired > > -disposition:1 lyrics+default+metadata -disposition:2 comment+forced > > -disposition:3 karaoke+captions+dub" "-map 0:0 -map 0:1 -c copy" "" > > "-show_entries > > stream_disposition:stream=index,codec_name:packet=stream_index,pts:packet_side_data_list > > -show_data_hash CRC32" > > > > +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, MATROSKA_DEMUXER) += > > fate-matroska-dovi-config-profile5 > > This should be FATE_MATROSKA_FFPROBE, not FATE_MATROSKA_FFMPEG_FFPROBE. > And actually, you need the file protocol; if you don't check for it, > you can just use FATE_MATROSKA_FFPROBE-$(CONFIG_MATROSKA_DEMUXER). > > > +fate-matroska-dovi-config-profile5: CMD = run ffprobe$(PROGSSUF)$(EXESUF) > > -show_entries stream_side_data_list -select_streams v -v 0 > > $(TARGET_SAMPLES)/mkv/dovi-p5.mkv > > + > > +FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL PIPE_PROTOCOL \ > > +MOV_DEMUXER MATROSKA_MUXER \ > > +FRAMECRC_MUXER) \ > > You will need the MATROSKA_DEMUXER, too; after all, the created file is > read and demuxed. Thanks again. Fixed along with the other comments (for the other patches). v12: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-January/290630.html > > + += fate-matroska-dovi-write-config > > +fate-matroska-dovi-write-config: CMD = transcode mov > > $(TARGET_SAMPLES)/hevc/dv84.mov matroska "-c:v copy" "-map 0 -c copy" "" > > "-show_entries stream_side_data_list -select_streams v -v 0" > > + > > FATE_SAMPLES_AVCONV += $(FATE_MATROSKA-yes) > > FATE_SAMPLES_FFPROBE += $(FATE_MATROSKA_FFPROBE-yes) > > FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_MATROSKA_FFMPEG_FFPROBE-yes) > ___ > 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". ___ 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".
[FFmpeg-devel] [PATCH 1/5] avformat/matroskadec: Parse Block Additional Mapping elements
Most of the implementation was done by the Plex developers. Signed-off-by: quietvoid --- libavformat/matroska.h| 7 ++ libavformat/matroskadec.c | 45 +-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..4b2a3310a4 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 500c83ac3a..8ae553953d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -239,6 +239,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +int value; +char *name; +int type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +276,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +427,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +578,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_OF(matroska_track) }; +static EbmlSyntax matroska_block_addition_mapping[] = { +{ MATROSKA_ID_BLKADDIDVALUE, EBML_UINT, 0, 0, offsetof(MatroskaBlockAdditionMapping, value) }, +{ MATROSKA_ID_BLKADDIDNAME, EBML_STR, 0, 0, offsetof(MatroskaBlockAdditionMapping, name) }, +{ MATROSKA_ID_BLKADDIDTYPE, EBML_UINT, 0, 0, offsetof(MatroskaBlockAdditionMapping, type) }, +{ MATROSKA_ID_BLKADDIDEXTRADATA, EBML_BIN, 0, 0, offsetof(MatroskaBlockAdditionMapping, extradata) }, +CHILD_OF(matroska_track) +}; + static EbmlSyntax matroska_track[] = { { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, 0, offsetof(MatroskaTrack, num) }, { MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, 0, offsetof(MatroskaTrack, name) }, @@ -593,6 +609,7 @@ static EbmlSyntax matroska_track[] = { { MATROSKA_ID_TRACKOPERATION,EBML_NEST, 0, 0, offsetof(MatroskaTrack, operation),{ .n = matroska_track_operation } }, { MATROSKA_ID_TRACKCONTENTENCODINGS, EBML_NEST, 0, 0, 0, { .n = matroska_track_encodings } }, { MATROSKA_ID_TRACKMAXBLKADDID, EBML_UINT, 0, 0, offsetof(MatroskaTrack, max_block_additional_id), { .u = 0 } }, +{ MATROSKA_ID_TRACKBLKADDMAPPING,EBML_NEST, 0, sizeof(MatroskaBlockAdditionMapping), offsetof(MatroskaTrack, block_addition_mappings), { .n = matroska_block_addition_mapping } }, { MATROSKA_ID_SEEKPREROLL, EBML_UINT, 0, 0, offsetof(MatroskaTrack, seek_preroll), { .u = 0 } }, { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE }, { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE }, @@ -2306,6 +2323,26 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track, return 0; } +static int mkv_parse_block_addition_mappings(AVFormatContext *s, AVStream *st, const MatroskaTrack *track) +{ +int i, ret; +const EbmlList *mappings_list = &track->block_addition_mappings; +MatroskaBlockAdditionMapping *mappings = mappin
[FFmpeg-devel] [PATCH 2/5] avformat/matroskadec: Parse dvcC/dvvC block additional mapping
The parsing was implemented in isom, for the unification of the mov/mpegts DOVI parsing into one function, in a later patch. Most of the implementation was done by Plex developers. Signed-off-by: quietvoid --- libavformat/isom.c| 51 +++ libavformat/isom.h| 5 libavformat/matroskadec.c | 13 ++ 3 files changed, 69 insertions(+) diff --git a/libavformat/isom.c b/libavformat/isom.c index 4df5440023..80a8f4d7b0 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -430,3 +430,54 @@ void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout) } avio_wb32(pb, 0); // mNumberChannelDescriptions } + +int ff_mov_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, GetBitContext *gb) +{ +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (gb->size_in_bits < 32) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = get_bits(gb, 8); +dovi->dv_version_minor = get_bits(gb, 8); + +dovi->dv_profile= get_bits(gb, 7); +dovi->dv_level = get_bits(gb, 6); +dovi->rpu_present_flag = get_bits1(gb); +dovi->el_present_flag = get_bits1(gb); +dovi->bl_present_flag = get_bits1(gb); + +// Has enough remaining data +if (gb->size_in_bits >= 36) { +dovi->dv_bl_signal_compatibility_id = get_bits(gb, 4); +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id +); + +return 0; +} diff --git a/libavformat/isom.h b/libavformat/isom.h index 34a58c79b7..44bd839852 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -27,6 +27,9 @@ #include #include +#include "libavcodec/get_bits.h" + +#include "libavutil/dovi_meta.h" #include "libavutil/encryption_info.h" #include "libavutil/mastering_display_metadata.h" #include "libavutil/spherical.h" @@ -390,4 +393,6 @@ static inline enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags) #define MOV_ISMV_TTML_TAG MKTAG('d', 'f', 'x', 'p') #define MOV_MP4_TTML_TAG MKTAG('s', 't', 'p', 'p') +int ff_mov_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, GetBitContext *gb); + #endif /* AVFORMAT_ISOM_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 8ae553953d..4633067d48 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2323,6 +2323,14 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track, return 0; } +static int mkv_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const MatroskaTrack *track, + EbmlBin *bin) +{ +GetBitContext gb; +init_get_bits8(&gb, bin->data, bin->size); +return ff_mov_parse_dvcc_dvvc(s, st, &gb); +} + static int mkv_parse_block_addition_mappings(AVFormatContext *s, AVStream *st, const MatroskaTrack *track) { int i, ret; @@ -2333,6 +2341,11 @@ static int mkv_parse_block_addition_mappings(AVFormatContext *s, AVStream *st, c MatroskaBlockAdditionMapping *mapping = &mappings[i]; switch (mapping->type) { +case MKBETAG('d','v','c','C'): +case MKBETAG('d','v','v','C'): +if ((ret = mkv_parse_dvcc_dvvc(s, st, track, &mapping->extradata)) < 0) +return ret; +break; default: av_log(s, AV_LOG_DEBUG, "Unknown block additional mapping type %i, value %i, name \"%s\"\n", -- 2.33.0 ___ 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".
[FFmpeg-devel] [PATCH 3/5] avformat/matroskaenc: Write dvcC/dvvC block additional mapping
When muxing to Matroska, write the Block Additional Mapping if there is AV_PKT_DATA_DOVI_CONF side data present. Most of the code was implemented by Plex developers. Signed-off-by: quietvoid --- libavformat/isom.c| 42 +++ libavformat/isom.h| 4 libavformat/matroskaenc.c | 33 ++ 3 files changed, 79 insertions(+) diff --git a/libavformat/isom.c b/libavformat/isom.c index 80a8f4d7b0..a5eb2e0caf 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -481,3 +481,45 @@ int ff_mov_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, GetBitContext *gb) return 0; } + +int ff_mov_put_dvcc_dvvc(AVFormatContext *s, uint8_t *out, int size, uint32_t *type, + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; +init_put_bits(&pb, out, size); + +if (size < MOV_DVCC_DVVC_SIZE) +return AVERROR(EINVAL); + +if (dovi->dv_profile > 7) +*type = MKBETAG('d', 'v', 'v', 'C'); +else +*type = MKBETAG('d', 'v', 'c', 'C'); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id); +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_profile > 7 ? "dvvC" : "dvcC", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id); + +return put_bits_count(&pb) / 8; +} diff --git a/libavformat/isom.h b/libavformat/isom.h index 44bd839852..6214180c00 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -28,6 +28,7 @@ #include #include "libavcodec/get_bits.h" +#include "libavcodec/put_bits.h" #include "libavutil/dovi_meta.h" #include "libavutil/encryption_info.h" @@ -393,6 +394,9 @@ static inline enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags) #define MOV_ISMV_TTML_TAG MKTAG('d', 'f', 'x', 'p') #define MOV_MP4_TTML_TAG MKTAG('s', 't', 'p', 'p') +#define MOV_DVCC_DVVC_SIZE 24 int ff_mov_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, GetBitContext *gb); +int ff_mov_put_dvcc_dvvc(AVFormatContext *s, uint8_t *out, int size, uint32_t *type, + AVDOVIDecoderConfigurationRecord *dovi); #endif /* AVFORMAT_ISOM_H */ diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 039f20988a..e99bd655cc 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1115,6 +1115,33 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, return 0; } +static int mkv_write_dovi(AVFormatContext *s, AVIOContext *pb, AVStream *st) +{ +int ret; +AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *) + av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF, NULL); + +if (dovi) { +ebml_master mapping; +uint8_t buf[MOV_DVCC_DVVC_SIZE]; +uint32_t type; +int size; + +if ((ret = ff_mov_put_dvcc_dvvc(s, buf, sizeof(buf), &type, dovi)) < 0) +return ret; + +size = ret; + +mapping = start_ebml_master(pb, MATROSKA_ID_TRACKBLKADDMAPPING, 0); +put_ebml_string(pb, MATROSKA_ID_BLKADDIDNAME, "Dolby Vision configuration"); +put_ebml_uint(pb, MATROSKA_ID_BLKADDIDTYPE, type); +put_ebml_binary(pb, MATROSKA_ID_BLKADDIDEXTRADATA, buf, size); +end_ebml_master(pb, mapping); +} + +return 0; +} + static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, AVStream *st, mkv_track *track, AVIOContext *pb, int is_default) @@ -1380,6 +1407,12 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, return AVERROR(EINVAL); } +
[FFmpeg-devel] [PATCH 4/5] avformat/mov: Refactor DOVI box parsing to use ff_mov_parse_dvcc_dvvc
Read at most 24 bytes, but in reality only 5 bytes are used for parsing. The rest of the bytes are reserved in the specification. Signed-off-by: quietvoid --- libavformat/mov.c | 48 +-- 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index ca14646a38..d3c483a2f1 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6797,10 +6797,10 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[MOV_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; +GetBitContext gb; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; @@ -6809,46 +6809,16 @@ static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) if ((uint64_t)atom.size > (1<<30) || atom.size < 4) return AVERROR_INVALIDDATA; -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > MOV_DVCC_DVVC_SIZE) { +read_size = MOV_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ffio_read_size(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); - -return 0; +init_get_bits8(&gb, buf, read_size); +return ff_mov_parse_dvcc_dvvc(c->fc, st, &gb); } static const MOVParseTableEntry mov_default_parse_table[] = { -- 2.33.0 ___ 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".
[FFmpeg-devel] [PATCH 5/5] avformat/mpegts: Refactor DOVI descriptor parsing to use ff_mov_parse_dvcc_dvvc
Signed-off-by: quietvoid --- libavformat/mpegts.c | 41 +++-- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index da8eee2414..19d26ef375 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -2162,49 +2162,14 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type break; case 0xb0: /* DOVI video stream descriptor */ { -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +GetBitContext gb; int ret; -if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + 1) / 8 -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); -dovi->dv_version_major = get8(pp, desc_end); -dovi->dv_version_minor = get8(pp, desc_end); -buf = get16(pp, desc_end); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (desc_end - *pp >= 20) { // 4 + 4 * 4 -buf = get8(pp, desc_end); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; -} +init_get_bits8(&gb, *pp, desc_len); -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ff_mov_parse_dvcc_dvvc(fc, st, &gb)) < 0) { return ret; } - -av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); } break; default: -- 2.33.0 ___ 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".
Re: [FFmpeg-devel] [PATCH 1/5] avformat/matroskadec: Parse Block Additional Mapping elements
On 22/09/2021 20.55, Andreas Rheinhardt wrote: quietvoid: Most of the implementation was done by the Plex developers. Signed-off-by: quietvoid ---  libavformat/matroska.h   | 7 ++  libavformat/matroskadec.c | 45 +--  2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..4b2a3310a4 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@  #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240  #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F  #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4   /* IDs in the trackvideo master */  #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@  #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4  #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3  +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED +  /* ID in the cues master */  #define MATROSKA_ID_POINTENTRY 0xBB  diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 500c83ac3a..8ae553953d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -239,6 +239,13 @@ typedef struct MatroskaTrackOperation {  EbmlList combine_planes;  } MatroskaTrackOperation;  +typedef struct MatroskaBlockAdditionMapping { +   int value; +   char *name; +   int type; This is wrong and won't work on big endian systems: Our EBML_UINT always expects a target element of type uint64_t. Okay, will change to uint64_t. I'm new to this, am I just supposed to update the patches locally and send them as a new version once the whole series is reviewed? Sorry, think I responded to the wrong email. ___ 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".
Re: [FFmpeg-devel] [PATCH 3/5] avformat/matroskaenc: Write dvcC/dvvC block additional mapping
On 22/09/2021 22.03, Andreas Rheinhardt wrote: quietvoid: +put_ebml_string(pb, MATROSKA_ID_BLKADDIDNAME, "Dolby Vision configuration"); +put_ebml_uint(pb, MATROSKA_ID_BLKADDIDTYPE, type); +put_ebml_binary(pb, MATROSKA_ID_BLKADDIDEXTRADATA, buf, size); +end_ebml_master(pb, mapping); +} + +return 0; +} + static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, AVStream *st, mkv_track *track, AVIOContext *pb, int is_default) @@ -1380,6 +1407,12 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, return AVERROR(EINVAL); } +// After video track, before private data Is this required? No, if DOVI side data can be assumed to always be along a video track. Which is the case, I think. The order is not necessary but this is the same behaviour as other Matroska muxers. I've simply validated the elements with mkvinfo. ___ 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".
[FFmpeg-devel] [PATCH v2 1/5] avformat/matroskadec: Parse Block Additional Mapping elements
Most of the implementation was done by the Plex developers. Signed-off-by: quietvoid --- libavformat/matroska.h| 7 ++ libavformat/matroskadec.c | 45 +-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..4b2a3310a4 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 500c83ac3a..25aa140e16 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -239,6 +239,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { +uint64_t value; +char *name; +uint64_t type; +EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +276,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; +EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +427,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +578,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_OF(matroska_track) }; +static EbmlSyntax matroska_block_addition_mapping[] = { +{ MATROSKA_ID_BLKADDIDVALUE, EBML_UINT, 0, 0, offsetof(MatroskaBlockAdditionMapping, value) }, +{ MATROSKA_ID_BLKADDIDNAME, EBML_STR, 0, 0, offsetof(MatroskaBlockAdditionMapping, name) }, +{ MATROSKA_ID_BLKADDIDTYPE, EBML_UINT, 0, 0, offsetof(MatroskaBlockAdditionMapping, type) }, +{ MATROSKA_ID_BLKADDIDEXTRADATA, EBML_BIN, 0, 0, offsetof(MatroskaBlockAdditionMapping, extradata) }, +CHILD_OF(matroska_track) +}; + static EbmlSyntax matroska_track[] = { { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, 0, offsetof(MatroskaTrack, num) }, { MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, 0, offsetof(MatroskaTrack, name) }, @@ -593,6 +609,7 @@ static EbmlSyntax matroska_track[] = { { MATROSKA_ID_TRACKOPERATION,EBML_NEST, 0, 0, offsetof(MatroskaTrack, operation),{ .n = matroska_track_operation } }, { MATROSKA_ID_TRACKCONTENTENCODINGS, EBML_NEST, 0, 0, 0, { .n = matroska_track_encodings } }, { MATROSKA_ID_TRACKMAXBLKADDID, EBML_UINT, 0, 0, offsetof(MatroskaTrack, max_block_additional_id), { .u = 0 } }, +{ MATROSKA_ID_TRACKBLKADDMAPPING,EBML_NEST, 0, sizeof(MatroskaBlockAdditionMapping), offsetof(MatroskaTrack, block_addition_mappings), { .n = matroska_block_addition_mapping } }, { MATROSKA_ID_SEEKPREROLL, EBML_UINT, 0, 0, offsetof(MatroskaTrack, seek_preroll), { .u = 0 } }, { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE }, { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE }, @@ -2306,6 +2323,26 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track, return 0; } +static int mkv_parse_block_addition_mappings(AVFormatContext *s, AVStream *st, const MatroskaTrack *track) +{ +int i, ret; +const EbmlList *mappings_list = &track->block_addition_mappings; +MatroskaBlockAdditionMapping *m
[FFmpeg-devel] [PATCH v2 2/5] avformat/matroskadec: Parse dvcC/dvvC block additional mapping
The parsing was implemented in a new dovi_isom file for the unification of the mov/mpegts DOVI parsing into one function, in a following patch. Most of the Matroska elements implementation was done by Plex developers. Signed-off-by: quietvoid --- libavformat/Makefile | 2 +- libavformat/dovi_isom.c | 80 +++ libavformat/dovi_isom.h | 29 ++ libavformat/matroskadec.c | 13 +++ 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 libavformat/dovi_isom.c create mode 100644 libavformat/dovi_isom.h diff --git a/libavformat/Makefile b/libavformat/Makefile index c45caa3eed..61a1fecf6c 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -313,7 +313,7 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ -qtpalette.o replaygain.o +qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c new file mode 100644 index 00..3eafa0d13b --- /dev/null +++ b/libavformat/dovi_isom.c @@ -0,0 +1,80 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * 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 "libavutil/dovi_meta.h" + +#include "avformat.h" +#include "dovi_isom.h" + +int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size) +{ +uint32_t buf; +AVDOVIDecoderConfigurationRecord *dovi; +size_t dovi_size; +int ret; + +if (size > (1<<30) || size < 4) +return AVERROR_INVALIDDATA; + +dovi = av_dovi_alloc(&dovi_size); +if (!dovi) +return AVERROR(ENOMEM); + +dovi->dv_version_major = *buf_ptr++;// 8 bits +dovi->dv_version_minor = *buf_ptr++;// 8 bits + +buf = *buf_ptr++ << 8; +buf |= *buf_ptr++; + +dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits +dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits +dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit +dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit +dovi->bl_present_flag = buf & 0x01;// 1 bit + +// Has enough remaining data +if (size >= 5) { +dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits +} else { +// 0 stands for None +// Dolby Vision V1.2.93 profiles and levels +dovi->dv_bl_signal_compatibility_id = 0; +} + +ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, + (uint8_t *)dovi, dovi_size); +if (ret < 0) { +av_free(dovi); +return ret; +} + +av_log(s, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id +); + +return 0; +} \ No newline at end of file diff --git a/libavformat/dovi_isom.h b/libavformat/dovi_isom.h new file mode 100644 index 00..9d9a05bdb0 --- /dev/null +++ b/libavformat/dovi_isom.h @@ -0,0 +1,29 @@ +/* + * DOVI ISO Media common code + * Copyright (c) 2021 quietvoid + * + * 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 F
[FFmpeg-devel] [PATCH v2 3/5] avformat/matroskaenc: Write dvcC/dvvC block additional mapping
When muxing to Matroska, write the Block Additional Mapping if there is AV_PKT_DATA_DOVI_CONF side data present. Most of the code was implemented by Plex developers. Signed-off-by: quietvoid --- libavformat/Makefile | 2 +- libavformat/dovi_isom.c | 45 +++ libavformat/dovi_isom.h | 5 + libavformat/matroskaenc.c | 32 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index 61a1fecf6c..680030014d 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -317,7 +317,7 @@ OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ OBJS-$(CONFIG_MATROSKA_MUXER)+= matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ -vorbiscomment.o wv.o +vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/dovi_isom.c b/libavformat/dovi_isom.c index 3eafa0d13b..15acc5cbce 100644 --- a/libavformat/dovi_isom.c +++ b/libavformat/dovi_isom.c @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavcodec/put_bits.h" + #include "libavutil/dovi_meta.h" #include "avformat.h" @@ -77,4 +79,47 @@ int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf ); return 0; +} + +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t *out, int size, uint32_t *type, + AVDOVIDecoderConfigurationRecord *dovi) +{ +PutBitContext pb; +init_put_bits(&pb, out, size); + +if (size < ISOM_DVCC_DVVC_SIZE) +return AVERROR(EINVAL); + +if (dovi->dv_profile > 7) +*type = MKBETAG('d', 'v', 'v', 'C'); +else +*type = MKBETAG('d', 'v', 'c', 'C'); + +put_bits(&pb, 8, dovi->dv_version_major); +put_bits(&pb, 8, dovi->dv_version_minor); +put_bits(&pb, 7, dovi->dv_profile); +put_bits(&pb, 6, dovi->dv_level); +put_bits(&pb, 1, dovi->rpu_present_flag); +put_bits(&pb, 1, dovi->el_present_flag); +put_bits(&pb, 1, dovi->bl_present_flag); +put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id); + +put_bits(&pb, 28, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +put_bits32(&pb, 0); /* reserved */ +flush_put_bits(&pb); + +av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, " + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", + dovi->dv_profile > 7 ? "dvvC" : "dvcC", + dovi->dv_version_major, dovi->dv_version_minor, + dovi->dv_profile, dovi->dv_level, + dovi->rpu_present_flag, + dovi->el_present_flag, + dovi->bl_present_flag, + dovi->dv_bl_signal_compatibility_id); + +return put_bytes_output(&pb); } \ No newline at end of file diff --git a/libavformat/dovi_isom.h b/libavformat/dovi_isom.h index 9d9a05bdb0..b58ab1bea0 100644 --- a/libavformat/dovi_isom.h +++ b/libavformat/dovi_isom.h @@ -23,7 +23,12 @@ #define AVFORMAT_DOVI_ISOM_H #include "avformat.h" +#include "libavutil/dovi_meta.h" + +#define ISOM_DVCC_DVVC_SIZE 24 int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size); +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t *out, int size, uint32_t *type, + AVDOVIDecoderConfigurationRecord *dovi); #endif /* AVFORMAT_DOVI_ISOM_H */ \ No newline at end of file diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 039f20988a..a54f7b5feb 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -54,6 +54,8 @@ #include "libavcodec/xiph.h" #include "libavcodec/mpeg4audio.h" +#include "libavformat/dovi_isom.h" + /* Level 1 elements we create a SeekHead entry for: * Info, Tracks, Chapters, Attachments, Tags (potentially twice) and Cues */ #define MAX_SEEKHEAD_ENTRIES 7 @@ -1115,6 +1117,33 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, return 0; } +static int mkv_write_dovi(AVFormatContext *s, AVIOContext *pb, AVStream *st) +{ +int ret; +AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigu
[FFmpeg-devel] [PATCH v2 4/5] avformat/mov: Refactor DOVI box parsing to use ff_isom_parse_dvcc_dvvc
Read at most 24 bytes, but in reality only 5 bytes are used for parsing. The rest of the bytes are reserved in the specification. Signed-off-by: quietvoid --- libavformat/mov.c | 51 ++- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index ca14646a38..07595ef769 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -61,6 +61,8 @@ #include "mov_chan.h" #include "replaygain.h" +#include "libavformat/dovi_isom.h" + #if CONFIG_ZLIB #include #endif @@ -6797,58 +6799,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; +uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; int ret; +int64_t read_size = atom.size; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; -if ((uint64_t)atom.size > (1<<30) || atom.size < 4) -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); - -dovi->dv_version_major = avio_r8(pb); -dovi->dv_version_minor = avio_r8(pb); - -buf = avio_rb16(pb); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (atom.size >= 24) { // 4 + 4 + 4 * 4 -buf = avio_r8(pb); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; +// At most 24 bytes +if (read_size > ISOM_DVCC_DVVC_SIZE) { +read_size = ISOM_DVCC_DVVC_SIZE; } -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ffio_read_size(pb, buf, read_size)) < 0) return ret; -} -av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id -); +read_size = ret; -return 0; +return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size); } static const MOVParseTableEntry mov_default_parse_table[] = { -- 2.33.0 ___ 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".
[FFmpeg-devel] [PATCH v2 5/5] avformat/mpegts: Refactor DOVI descriptor parsing to use ff_isom_parse_dvcc_dvvc
Signed-off-by: quietvoid --- libavformat/mpegts.c | 44 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index da8eee2414..75ef59d186 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -39,6 +39,9 @@ #include "avio_internal.h" #include "mpeg.h" #include "isom.h" + +#include "libavformat/dovi_isom.h" + #if CONFIG_ICONV #include #endif @@ -2162,49 +2165,10 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type break; case 0xb0: /* DOVI video stream descriptor */ { -uint32_t buf; -AVDOVIDecoderConfigurationRecord *dovi; -size_t dovi_size; int ret; -if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + 1) / 8 -return AVERROR_INVALIDDATA; - -dovi = av_dovi_alloc(&dovi_size); -if (!dovi) -return AVERROR(ENOMEM); -dovi->dv_version_major = get8(pp, desc_end); -dovi->dv_version_minor = get8(pp, desc_end); -buf = get16(pp, desc_end); -dovi->dv_profile= (buf >> 9) & 0x7f;// 7 bits -dovi->dv_level = (buf >> 3) & 0x3f;// 6 bits -dovi->rpu_present_flag = (buf >> 2) & 0x01;// 1 bit -dovi->el_present_flag = (buf >> 1) & 0x01;// 1 bit -dovi->bl_present_flag = buf & 0x01;// 1 bit -if (desc_end - *pp >= 20) { // 4 + 4 * 4 -buf = get8(pp, desc_end); -dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits -} else { -// 0 stands for None -// Dolby Vision V1.2.93 profiles and levels -dovi->dv_bl_signal_compatibility_id = 0; -} - -ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF, - (uint8_t *)dovi, dovi_size); -if (ret < 0) { -av_free(dovi); +if ((ret = ff_isom_parse_dvcc_dvvc(fc, st, *pp, desc_len)) < 0) return ret; -} - -av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " - "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n", - dovi->dv_version_major, dovi->dv_version_minor, - dovi->dv_profile, dovi->dv_level, - dovi->rpu_present_flag, - dovi->el_present_flag, - dovi->bl_present_flag, - dovi->dv_bl_signal_compatibility_id); } break; default: -- 2.33.0 ___ 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".
Re: [FFmpeg-devel] [PATCH v2 3/5] avformat/matroskaenc: Write dvcC/dvvC block additional mapping
On 23/09/2021 01.33, Andreas Rheinhardt wrote: diff --git a/libavformat/dovi_isom.h b/libavformat/dovi_isom.h index 9d9a05bdb0..b58ab1bea0 100644 --- a/libavformat/dovi_isom.h +++ b/libavformat/dovi_isom.h @@ -23,7 +23,12 @@ #define AVFORMAT_DOVI_ISOM_H #include "avformat.h" +#include "libavutil/dovi_meta.h" + +#define ISOM_DVCC_DVVC_SIZE 24 int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size); +int ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t *out, int size, uint32_t *type, + AVDOVIDecoderConfigurationRecord *dovi); #endif /* AVFORMAT_DOVI_ISOM_H */ \ No newline at end of file diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 039f20988a..a54f7b5feb 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -54,6 +54,8 @@ #include "libavcodec/xiph.h" #include "libavcodec/mpeg4audio.h" +#include "libavformat/dovi_isom.h" + /* Level 1 elements we create a SeekHead entry for: * Info, Tracks, Chapters, Attachments, Tags (potentially twice) and Cues */ #define MAX_SEEKHEAD_ENTRIES 7 @@ -1115,6 +1117,33 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, return 0; } +static int mkv_write_dovi(AVFormatContext *s, AVIOContext *pb, AVStream *st) +{ +int ret; +AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *) + av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF, NULL); + +if (dovi) { +ebml_master mapping; +uint8_t buf[ISOM_DVCC_DVVC_SIZE]; +uint32_t type; +int size; + +if ((ret = ff_isom_put_dvcc_dvvc(s, buf, sizeof(buf), &type, dovi)) < 0) +return ret; + +size = ret; + +mapping = start_ebml_master(pb, MATROSKA_ID_TRACKBLKADDMAPPING, ISOM_DVCC_DVVC_SIZE); This is wrong: ISOM_DVCC_DVVC_SIZE need not be an upper bound for the size of the blockgroup. (2 + 1 + strlen("Dolby Vision configuration")) + (2 + 1 + 4) + (2 + 1 + ISOM_DVCC_DVVC_SIZE) is -- although I'd prefer if you used sizeof("Dolby Vision configuration") - 1 instead of strlen. Okay, I was confused on what you meant previously. I have changed it to use this variable: uint64_t expected_size = (2 + 1 + (sizeof("Dolby Vision configuration") - 1)) + (2 + 1 + 4) + (2 + 1 + ISOM_DVCC_DVVC_SIZE); +put_ebml_string(pb, MATROSKA_ID_BLKADDIDNAME, "Dolby Vision configuration"); +put_ebml_uint(pb, MATROSKA_ID_BLKADDIDTYPE, type); +put_ebml_binary(pb, MATROSKA_ID_BLKADDIDEXTRADATA, buf, size); +end_ebml_master(pb, mapping); +} + +return 0; +} + static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, AVStream *st, mkv_track *track, AVIOContext *pb, int is_default) @@ -1380,6 +1409,9 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, return AVERROR(EINVAL); } +if ((ret = mkv_write_dovi(s, pb, st)) < 0) +return ret; Given that this is not part of WebM, there needs to be check for mkv->mode != MODE_WEBM. Furthermore, this should also be moved to the AVMEDIA_TYPE_VIDEO switch statement directly after the video master element has been closed. Corrected, thank you. Is it OK to resend a new version or should I wait in case more changes are necessary in the other patches? ___ 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".
[FFmpeg-devel] [PATCH v2 0/2] DOVI: Add NLQ pivots to AVDOVIDataMapping
The NLQ pivots are not documented but should be present in the header for profile 7 RPU format. It has been verified using Dolby's verification toolkit. With the pivots parsed, the parsed values for num_{x,y}_partitions are correct and usually equal to 1. Changes in v2: - Moved the `nlq_pivots` field at the end of AVDOVIDataMapping. quietvoid (2): libavutil/dovi_meta: Add nlq_pivots to AVDOVIDataMapping fate: Add test to parse profile 7 DOVI RPU fftools/ffprobe.c | 4 + libavcodec/dovi_rpu.c | 7 + libavfilter/vf_showinfo.c | 8 + libavutil/dovi_meta.h | 1 + tests/fate/hevc.mak | 3 + tests/ref/fate/hevc-dovi-profile7-rpu | 296 ++ 6 files changed, 319 insertions(+) create mode 100644 tests/ref/fate/hevc-dovi-profile7-rpu -- 2.36.1 ___ 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".
[FFmpeg-devel] [PATCH v2 1/2] libavutil/dovi_meta: Add nlq_pivots to AVDOVIDataMapping
The NLQ pivots are not documented but should be present in the header for profile 7 RPU format. It has been verified using Dolby's verification toolkit. Also implemented the parsing in libavcodec/dovi_rpu.c. And added the info to ffprobe and showinfo. Signed-off-by: quietvoid --- fftools/ffprobe.c | 4 libavcodec/dovi_rpu.c | 7 +++ libavfilter/vf_showinfo.c | 8 libavutil/dovi_meta.h | 1 + 4 files changed, 20 insertions(+) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 4e2fdbaec8..bc4f7ec0a1 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -2001,6 +2001,10 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi) break; } +if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) { +print_list_fmt("nlq_pivots", "%"PRIu16, 2, mapping->nlq_pivots[idx]); +} + print_int("num_x_partitions", mapping->num_x_partitions); print_int("num_y_partitions", mapping->num_y_partitions); diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index a87562c8a3..17837eb845 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -315,7 +315,14 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) } if (use_nlq) { +int nlq_pivot = 0; vdr->mapping.nlq_method_idc = get_bits(gb, 3); + +for (int i = 0; i < 2; i++) { +nlq_pivot += get_bits(gb, hdr->bl_bit_depth); +vdr->mapping.nlq_pivots[i] = av_clip_uint16(nlq_pivot); +} + /** * The patent mentions another legal value, NLQ_MU_LAW, but it's * not documented anywhere how to parse or apply that type of NLQ. diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index 6efcafce28..f8c04fb2fa 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -535,6 +535,14 @@ static void dump_dovi_metadata(AVFilterContext *ctx, const AVFrameSideData *sd) av_log(ctx, AV_LOG_INFO, "mapping_color_space=%"PRIu8"; ", mapping->mapping_color_space); av_log(ctx, AV_LOG_INFO, "mapping_chroma_format_idc=%"PRIu8"; ", mapping->mapping_chroma_format_idc); av_log(ctx, AV_LOG_INFO, "nlq_method_idc=%d; ", (int) mapping->nlq_method_idc); + +if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) { +av_log(ctx, AV_LOG_INFO, "nlq_pivots={ "); +for (int i = 0; i < 2; i++) +av_log(ctx, AV_LOG_INFO, "%"PRIu16" ", mapping->nlq_pivots[i]); +av_log(ctx, AV_LOG_INFO, "}; "); +} + av_log(ctx, AV_LOG_INFO, "num_x_partitions=%"PRIu32"; ", mapping->num_x_partitions); av_log(ctx, AV_LOG_INFO, "num_y_partitions=%"PRIu32"\n", mapping->num_y_partitions); diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h index 3d11e02bff..6afc7b055a 100644 --- a/libavutil/dovi_meta.h +++ b/libavutil/dovi_meta.h @@ -147,6 +147,7 @@ typedef struct AVDOVIDataMapping { uint32_t num_x_partitions; uint32_t num_y_partitions; AVDOVINLQParams nlq[3]; /* per component */ +uint16_t nlq_pivots[2]; /* nlq_pred_pivot_value */ } AVDOVIDataMapping; /** -- 2.36.1 ___ 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".
[FFmpeg-devel] [PATCH v2 2/2] fate: Add test to parse profile 7 DOVI RPU
Signed-off-by: quietvoid --- tests/fate/hevc.mak | 3 + tests/ref/fate/hevc-dovi-profile7-rpu | 296 ++ 2 files changed, 299 insertions(+) create mode 100644 tests/ref/fate/hevc-dovi-profile7-rpu diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index 2f16e3a29f..549436cb39 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -254,6 +254,9 @@ FATE_HEVC-$(call FRAMECRC, HEVC, HEVC) += fate-hevc-cabac-tudepth fate-hevc-small422chroma: CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc/food.hevc -pix_fmt yuv422p10le -vf scale FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, HEVC_PARSER SCALE_FILTER) += fate-hevc-small422chroma +fate-hevc-dovi-profile7-rpu: CMD = probeframes -show_entries frame=side_data_list -select_streams 1 -read_intervals "%+\#2" $(TARGET_SAMPLES)/mov/dovi-p7.mp4 +FATE_HEVC_FFPROBE-$(call DEMDEC, MOV, HEVC) += fate-hevc-dovi-profile7-rpu + FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) FATE_SAMPLES_FFPROBE += $(FATE_HEVC_FFPROBE-yes) diff --git a/tests/ref/fate/hevc-dovi-profile7-rpu b/tests/ref/fate/hevc-dovi-profile7-rpu new file mode 100644 index 00..7fa5d20f01 --- /dev/null +++ b/tests/ref/fate/hevc-dovi-profile7-rpu @@ -0,0 +1,296 @@ +[FRAME] +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=34000/5 +red_y=16000/5 +green_x=13250/5 +green_y=34500/5 +blue_x=7500/5 +blue_y=3000/5 +white_point_x=15635/5 +white_point_y=16450/5 +min_luminance=1/1 +max_luminance=1/1 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=400 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Dolby Vision RPU Data +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Dolby Vision Metadata +rpu_type=2 +rpu_format=18 +vdr_rpu_profile=1 +vdr_rpu_level=0 +chroma_resampling_explicit_filter_flag=0 +coef_data_type=0 +coef_log2_denom=23 +vdr_rpu_normalized_idc=1 +bl_video_full_range_flag=0 +bl_bit_depth=10 +el_bit_depth=10 +vdr_bit_depth=12 +spatial_resampling_filter_flag=0 +el_spatial_resampling_filter_flag=1 +disable_residual_flag=0 +vdr_rpu_id=0 +mapping_color_space=0 +mapping_chroma_format_idc=0 +nlq_method_idc=0 +nlq_method_idc_name=linear_dz +nlq_pivots=0 1023 +num_x_partitions=1 +num_y_partitions=1 +[COMPONENT] +pivots=0 128 256 384 512 640 768 896 1023 +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +nlq_offset=512 +vdr_in_max=1048576 +linear_deadzone_slope=2048 +linear_deadzone_threshold=0 +[/COMPONENT] +[COMPONENT] +pivots=0 1023 +[SECTION] +mapping_idc=1 +mapping_idc_name=mmr +mmr_order=3 +mmr_constant=448998 +mmr_coef=-1262056 8122466 -1703266 1622123 808554 -829469 -13459 801251 694657 3697830 -1819391 -772917 -654425 78034 -181321 -324811 -2213356 -716030 761880 365184 2545494 +[/SECTION] +nlq_offset=512 +vdr_in_max=1048576 +linear_deadzone_slope=2048 +linear_deadzone_threshold=0 +[/COMPONENT] +[COMPONENT] +pivots=0 1023 +[SECTION] +mapping_idc=1 +mapping_idc_name=mmr +mmr_order=3 +mmr_constant=30364 +mmr_coef=-1369971 645159 9055254 -106426 2546351 -2246880 672220 1356576 1789054 -3311517 -1372035 -4554569 -548063 722319 57239 -2130348 3956345 1480062 -1696575 3919674 3414157 +[/SECTION] +nlq_offset=512 +vdr_in_max=1048576 +linear_deadzone_slope=2048 +linear_deadzone_threshold=0 +[/COMPONENT] +dm_metadata_id=0 +scene_refresh_flag=0 +ycc_to_rgb_matrix=9574/8192 0/8192 13802/8192 9574/8192 -1540/8192 -5348/8192 9574/8192 17610/8192 0/8192 +ycc_to_rgb_offset=16777216/268435456 134217728/268435456 134217728/268435456 +rgb_to_lms_matrix=7222/16384 8771/16384 390/16384 2654/16384 12430/16384 1300/16384 0/16384 422/16384 15962/16384 +signal_eotf=65535 +signal_eotf_param0=0 +signal_eotf_param1=0 +signal_eotf_param2=0 +signal_bit_depth=12 +signal_color_space=0 +signal_chroma_format=0 +signal_full_range_flag=1 +source_min_pq=7 +source_max_pq=3079 +source_diagonal=42 +[/SIDE_DATA] +[/FRAME] +[FRAME] +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=34000/5 +red_y=16000/5 +green_x=13250/5 +green_y=34500/5 +blue_x=7500/5 +blue_y=3000/5 +white_point_x=15635/5 +white_point_y=16450/5 +min_luminance=1/1 +max_luminance=1/1 +[
Re: [FFmpeg-devel] [PATCH 1/2] libavutil/dovi_meta: Add nlq_pivots to AVDOVIDataMapping
On Sat, Jun 11, 2022 at 12:48 PM Andreas Rheinhardt wrote: > > quietvoid: > > The NLQ pivots are not documented but should be present > > in the header for profile 7 RPU format. > > It has been verified using Dolby's verification toolkit. > > > > Also implemented the parsing in libavcodec/dovi_rpu.c. > > And added the info to ffprobe and showinfo. > > --- > > fftools/ffprobe.c | 4 > > libavcodec/dovi_rpu.c | 7 +++ > > libavfilter/vf_showinfo.c | 8 > > libavutil/dovi_meta.h | 1 + > > 4 files changed, 20 insertions(+) > > > > diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c > > index c44297c1fa..63eb9b32ae 100644 > > --- a/fftools/ffprobe.c > > +++ b/fftools/ffprobe.c > > @@ -1934,6 +1934,10 @@ static void print_dovi_metadata(WriterContext *w, > > const AVDOVIMetadata *dovi) > > break; > > } > > > > +if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) { > > +print_list_fmt("nlq_pivots", "%"PRIu16, 2, > > mapping->nlq_pivots[idx]); > > +} > > + > > print_int("num_x_partitions", mapping->num_x_partitions); > > print_int("num_y_partitions", mapping->num_y_partitions); > > > > diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c > > index a87562c8a3..17837eb845 100644 > > --- a/libavcodec/dovi_rpu.c > > +++ b/libavcodec/dovi_rpu.c > > @@ -315,7 +315,14 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t > > *rpu, size_t rpu_size) > > } > > > > if (use_nlq) { > > +int nlq_pivot = 0; > > vdr->mapping.nlq_method_idc = get_bits(gb, 3); > > + > > +for (int i = 0; i < 2; i++) { > > +nlq_pivot += get_bits(gb, hdr->bl_bit_depth); > > +vdr->mapping.nlq_pivots[i] = av_clip_uint16(nlq_pivot); > > +} > > + > > /** > > * The patent mentions another legal value, NLQ_MU_LAW, but > > it's > > * not documented anywhere how to parse or apply that type of > > NLQ. > > diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c > > index 12d39310ef..2148d202b1 100644 > > --- a/libavfilter/vf_showinfo.c > > +++ b/libavfilter/vf_showinfo.c > > @@ -543,6 +543,14 @@ static void dump_dovi_metadata(AVFilterContext *ctx, > > const AVFrameSideData *sd) > > av_log(ctx, AV_LOG_INFO, "mapping_color_space=%"PRIu8"; ", > > mapping->mapping_color_space); > > av_log(ctx, AV_LOG_INFO, "mapping_chroma_format_idc=%"PRIu8"; ", > > mapping->mapping_chroma_format_idc); > > av_log(ctx, AV_LOG_INFO, "nlq_method_idc=%d; ", (int) > > mapping->nlq_method_idc); > > + > > +if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) { > > +av_log(ctx, AV_LOG_INFO, "nlq_pivots={ "); > > +for (int i = 0; i < 2; i++) > > +av_log(ctx, AV_LOG_INFO, "%"PRIu16" ", mapping->nlq_pivots[i]); > > +av_log(ctx, AV_LOG_INFO, "}; "); > > +} > > + > > av_log(ctx, AV_LOG_INFO, "num_x_partitions=%"PRIu32"; ", > > mapping->num_x_partitions); > > av_log(ctx, AV_LOG_INFO, "num_y_partitions=%"PRIu32"\n", > > mapping->num_y_partitions); > > > > diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h > > index 3d11e02bff..c7c5ba721f 100644 > > --- a/libavutil/dovi_meta.h > > +++ b/libavutil/dovi_meta.h > > @@ -144,6 +144,7 @@ typedef struct AVDOVIDataMapping { > > > > /* Non-linear inverse quantization */ > > enum AVDOVINLQMethod nlq_method_idc; > > +uint16_t nlq_pivots[2]; /* nlq_pred_pivot_value */ > > uint32_t num_x_partitions; > > uint32_t num_y_partitions; > > AVDOVINLQParams nlq[3]; /* per component */ > > This breaks ABI. New fields must be added at the end. Thanks. Fixed in v2: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-June/297723.html > > - Andreas > ___ > 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". ___ 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".
[FFmpeg-devel] [PATCH v3 0/4] DOVI: Add NLQ pivots to AVDOVIDataMapping
The NLQ pivots are not documented but should be present in the header for profile 7 RPU format. It has been verified using Dolby's verification toolkit. With the pivots parsed, the parsed values for num_{x,y}_partitions are correct and usually equal to 1. Changes in v3: - Corrected AVDOVIDataMapping end offset for copy. - Split logging patches and consolidated show_info logging into one call. quietvoid (4): libavutil/dovi_meta: Add nlq_pivots to AVDOVIDataMapping fftools/ffprobe: Add DOVI nlq_pivots logging libavfilter/vf_showinfo: Add DOVI nlq_pivots logging fate: Add test to parse profile 7 DOVI RPU fftools/ffprobe.c | 4 + libavcodec/dovi_rpu.c | 9 +- libavfilter/vf_showinfo.c | 6 + libavutil/dovi_meta.h | 1 + tests/fate/hevc.mak | 3 + tests/ref/fate/hevc-dovi-profile7-rpu | 296 ++ 6 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 tests/ref/fate/hevc-dovi-profile7-rpu -- 2.36.1 ___ 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".
[FFmpeg-devel] [PATCH v3 1/4] libavutil/dovi_meta: Add nlq_pivots to AVDOVIDataMapping
The NLQ pivots are not documented but should be present in the header for profile 7 RPU format. It has been verified using Dolby's verification toolkit. Signed-off-by: quietvoid --- libavcodec/dovi_rpu.c | 9 - libavutil/dovi_meta.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index a87562c8a3..31e87cfbcc 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -117,7 +117,7 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame) /* Copy only the parts of these structs known to us at compiler-time. */ #define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last)) COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, disable_residual_flag); -COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq[2].linear_deadzone_threshold); +COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots[1]); COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal); return 0; } @@ -315,7 +315,14 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) } if (use_nlq) { +int nlq_pivot = 0; vdr->mapping.nlq_method_idc = get_bits(gb, 3); + +for (int i = 0; i < 2; i++) { +nlq_pivot += get_bits(gb, hdr->bl_bit_depth); +vdr->mapping.nlq_pivots[i] = av_clip_uint16(nlq_pivot); +} + /** * The patent mentions another legal value, NLQ_MU_LAW, but it's * not documented anywhere how to parse or apply that type of NLQ. diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h index 3d11e02bff..6afc7b055a 100644 --- a/libavutil/dovi_meta.h +++ b/libavutil/dovi_meta.h @@ -147,6 +147,7 @@ typedef struct AVDOVIDataMapping { uint32_t num_x_partitions; uint32_t num_y_partitions; AVDOVINLQParams nlq[3]; /* per component */ +uint16_t nlq_pivots[2]; /* nlq_pred_pivot_value */ } AVDOVIDataMapping; /** -- 2.36.1 ___ 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".
[FFmpeg-devel] [PATCH v3 2/4] fftools/ffprobe: Add DOVI nlq_pivots logging
Signed-off-by: quietvoid --- fftools/ffprobe.c | 4 1 file changed, 4 insertions(+) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 4e2fdbaec8..bc4f7ec0a1 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -2001,6 +2001,10 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi) break; } +if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) { +print_list_fmt("nlq_pivots", "%"PRIu16, 2, mapping->nlq_pivots[idx]); +} + print_int("num_x_partitions", mapping->num_x_partitions); print_int("num_y_partitions", mapping->num_y_partitions); -- 2.36.1 ___ 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".
[FFmpeg-devel] [PATCH v3 3/4] libavfilter/vf_showinfo: Add DOVI nlq_pivots logging
Signed-off-by: quietvoid --- libavfilter/vf_showinfo.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index 6efcafce28..5dce46dbdf 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -535,6 +535,12 @@ static void dump_dovi_metadata(AVFilterContext *ctx, const AVFrameSideData *sd) av_log(ctx, AV_LOG_INFO, "mapping_color_space=%"PRIu8"; ", mapping->mapping_color_space); av_log(ctx, AV_LOG_INFO, "mapping_chroma_format_idc=%"PRIu8"; ", mapping->mapping_chroma_format_idc); av_log(ctx, AV_LOG_INFO, "nlq_method_idc=%d; ", (int) mapping->nlq_method_idc); + +if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) { +av_log(ctx, AV_LOG_INFO, "nlq_pivots={ %"PRIu16" %"PRIu16" }; ", + mapping->nlq_pivots[0], mapping->nlq_pivots[1]); +} + av_log(ctx, AV_LOG_INFO, "num_x_partitions=%"PRIu32"; ", mapping->num_x_partitions); av_log(ctx, AV_LOG_INFO, "num_y_partitions=%"PRIu32"\n", mapping->num_y_partitions); -- 2.36.1 ___ 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".
[FFmpeg-devel] [PATCH v3 4/4] fate: Add test to parse profile 7 DOVI RPU
Signed-off-by: quietvoid --- tests/fate/hevc.mak | 3 + tests/ref/fate/hevc-dovi-profile7-rpu | 296 ++ 2 files changed, 299 insertions(+) create mode 100644 tests/ref/fate/hevc-dovi-profile7-rpu diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index 2f16e3a29f..549436cb39 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -254,6 +254,9 @@ FATE_HEVC-$(call FRAMECRC, HEVC, HEVC) += fate-hevc-cabac-tudepth fate-hevc-small422chroma: CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/hevc/food.hevc -pix_fmt yuv422p10le -vf scale FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, HEVC_PARSER SCALE_FILTER) += fate-hevc-small422chroma +fate-hevc-dovi-profile7-rpu: CMD = probeframes -show_entries frame=side_data_list -select_streams 1 -read_intervals "%+\#2" $(TARGET_SAMPLES)/mov/dovi-p7.mp4 +FATE_HEVC_FFPROBE-$(call DEMDEC, MOV, HEVC) += fate-hevc-dovi-profile7-rpu + FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) FATE_SAMPLES_FFPROBE += $(FATE_HEVC_FFPROBE-yes) diff --git a/tests/ref/fate/hevc-dovi-profile7-rpu b/tests/ref/fate/hevc-dovi-profile7-rpu new file mode 100644 index 00..7fa5d20f01 --- /dev/null +++ b/tests/ref/fate/hevc-dovi-profile7-rpu @@ -0,0 +1,296 @@ +[FRAME] +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=34000/5 +red_y=16000/5 +green_x=13250/5 +green_y=34500/5 +blue_x=7500/5 +blue_y=3000/5 +white_point_x=15635/5 +white_point_y=16450/5 +min_luminance=1/1 +max_luminance=1/1 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=400 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Dolby Vision RPU Data +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Dolby Vision Metadata +rpu_type=2 +rpu_format=18 +vdr_rpu_profile=1 +vdr_rpu_level=0 +chroma_resampling_explicit_filter_flag=0 +coef_data_type=0 +coef_log2_denom=23 +vdr_rpu_normalized_idc=1 +bl_video_full_range_flag=0 +bl_bit_depth=10 +el_bit_depth=10 +vdr_bit_depth=12 +spatial_resampling_filter_flag=0 +el_spatial_resampling_filter_flag=1 +disable_residual_flag=0 +vdr_rpu_id=0 +mapping_color_space=0 +mapping_chroma_format_idc=0 +nlq_method_idc=0 +nlq_method_idc_name=linear_dz +nlq_pivots=0 1023 +num_x_partitions=1 +num_y_partitions=1 +[COMPONENT] +pivots=0 128 256 384 512 640 768 896 1023 +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +[SECTION] +mapping_idc=0 +mapping_idc_name=polynomial +poly_order=1 +poly_coef=0 8388608 +[/SECTION] +nlq_offset=512 +vdr_in_max=1048576 +linear_deadzone_slope=2048 +linear_deadzone_threshold=0 +[/COMPONENT] +[COMPONENT] +pivots=0 1023 +[SECTION] +mapping_idc=1 +mapping_idc_name=mmr +mmr_order=3 +mmr_constant=448998 +mmr_coef=-1262056 8122466 -1703266 1622123 808554 -829469 -13459 801251 694657 3697830 -1819391 -772917 -654425 78034 -181321 -324811 -2213356 -716030 761880 365184 2545494 +[/SECTION] +nlq_offset=512 +vdr_in_max=1048576 +linear_deadzone_slope=2048 +linear_deadzone_threshold=0 +[/COMPONENT] +[COMPONENT] +pivots=0 1023 +[SECTION] +mapping_idc=1 +mapping_idc_name=mmr +mmr_order=3 +mmr_constant=30364 +mmr_coef=-1369971 645159 9055254 -106426 2546351 -2246880 672220 1356576 1789054 -3311517 -1372035 -4554569 -548063 722319 57239 -2130348 3956345 1480062 -1696575 3919674 3414157 +[/SECTION] +nlq_offset=512 +vdr_in_max=1048576 +linear_deadzone_slope=2048 +linear_deadzone_threshold=0 +[/COMPONENT] +dm_metadata_id=0 +scene_refresh_flag=0 +ycc_to_rgb_matrix=9574/8192 0/8192 13802/8192 9574/8192 -1540/8192 -5348/8192 9574/8192 17610/8192 0/8192 +ycc_to_rgb_offset=16777216/268435456 134217728/268435456 134217728/268435456 +rgb_to_lms_matrix=7222/16384 8771/16384 390/16384 2654/16384 12430/16384 1300/16384 0/16384 422/16384 15962/16384 +signal_eotf=65535 +signal_eotf_param0=0 +signal_eotf_param1=0 +signal_eotf_param2=0 +signal_bit_depth=12 +signal_color_space=0 +signal_chroma_format=0 +signal_full_range_flag=1 +source_min_pq=7 +source_max_pq=3079 +source_diagonal=42 +[/SIDE_DATA] +[/FRAME] +[FRAME] +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=34000/5 +red_y=16000/5 +green_x=13250/5 +green_y=34500/5 +blue_x=7500/5 +blue_y=3000/5 +white_point_x=15635/5 +white_point_y=16450/5 +min_luminance=1/1 +max_luminance=1/1 +[
Re: [FFmpeg-devel] [PATCH v2 1/2] libavutil/dovi_meta: Add nlq_pivots to AVDOVIDataMapping
On Fri, Jun 17, 2022 at 4:20 PM Andreas Rheinhardt wrote: > > quietvoid: > > The NLQ pivots are not documented but should be present > > in the header for profile 7 RPU format. > > It has been verified using Dolby's verification toolkit. > > > > Also implemented the parsing in libavcodec/dovi_rpu.c. > > And added the info to ffprobe and showinfo. > > > > Signed-off-by: quietvoid > > --- > > fftools/ffprobe.c | 4 > > libavcodec/dovi_rpu.c | 7 +++ > > libavfilter/vf_showinfo.c | 8 > > libavutil/dovi_meta.h | 1 + > > 4 files changed, 20 insertions(+) > > > > diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c > > index 4e2fdbaec8..bc4f7ec0a1 100644 > > --- a/fftools/ffprobe.c > > +++ b/fftools/ffprobe.c > > @@ -2001,6 +2001,10 @@ static void print_dovi_metadata(WriterContext *w, > > const AVDOVIMetadata *dovi) > > break; > > } > > > > +if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) { > > +print_list_fmt("nlq_pivots", "%"PRIu16, 2, > > mapping->nlq_pivots[idx]); > > +} > > + > > print_int("num_x_partitions", mapping->num_x_partitions); > > print_int("num_y_partitions", mapping->num_y_partitions); > > > > diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c > > index a87562c8a3..17837eb845 100644 > > --- a/libavcodec/dovi_rpu.c > > +++ b/libavcodec/dovi_rpu.c > > @@ -315,7 +315,14 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t > > *rpu, size_t rpu_size) > > } > > > > if (use_nlq) { > > +int nlq_pivot = 0; > > vdr->mapping.nlq_method_idc = get_bits(gb, 3); > > + > > +for (int i = 0; i < 2; i++) { > > +nlq_pivot += get_bits(gb, hdr->bl_bit_depth); > > +vdr->mapping.nlq_pivots[i] = av_clip_uint16(nlq_pivot); > > +} > > + > > /** > > * The patent mentions another legal value, NLQ_MU_LAW, but > > it's > > * not documented anywhere how to parse or apply that type of > > NLQ. > > diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c > > index 6efcafce28..f8c04fb2fa 100644 > > --- a/libavfilter/vf_showinfo.c > > +++ b/libavfilter/vf_showinfo.c > > @@ -535,6 +535,14 @@ static void dump_dovi_metadata(AVFilterContext *ctx, > > const AVFrameSideData *sd) > > av_log(ctx, AV_LOG_INFO, "mapping_color_space=%"PRIu8"; ", > > mapping->mapping_color_space); > > av_log(ctx, AV_LOG_INFO, "mapping_chroma_format_idc=%"PRIu8"; ", > > mapping->mapping_chroma_format_idc); > > av_log(ctx, AV_LOG_INFO, "nlq_method_idc=%d; ", (int) > > mapping->nlq_method_idc); > > + > > +if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) { > > +av_log(ctx, AV_LOG_INFO, "nlq_pivots={ "); > > +for (int i = 0; i < 2; i++) > > +av_log(ctx, AV_LOG_INFO, "%"PRIu16" ", mapping->nlq_pivots[i]); > > +av_log(ctx, AV_LOG_INFO, "}; "); > > Don't use four calls to av_log for something that is so simple. Besides > having higher overhead and binary size it also adds the risk that these > av_logs are disturbed by another av_log in the middle, breaking the > output (at least with the default log callback). Fixed in v3. I've made it into a single log call: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-June/297733.html > (The same btw applies to other av_logs in this very function. Is it > actually intended for this to be one big line?) I'm not exactly sure how the showinfo filters usually look like. I'm only basing this on the existing logging for this part. > > > +} > > + > > av_log(ctx, AV_LOG_INFO, "num_x_partitions=%"PRIu32"; ", > > mapping->num_x_partitions); > > av_log(ctx, AV_LOG_INFO, "num_y_partitions=%"PRIu32"\n", > > mapping->num_y_partitions); > > > > diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h > > index 3d11e02bff..6afc7b055a 100644 > > --- a/libavutil/dovi_meta.h > > +++ b/libavutil/dovi_meta.h > > @@ -147,6 +147,7 @@ typedef struct AVDOVIDataMapping { > > uint32_t num_x_partitions; > > uint32_t num_y_partitions; > > AVDOVINLQParams nlq[3]; /* per component */ > > +uint16_t nlq_pivots[2]; /* nlq_pred_pivot_value */ > > } AVDOVIDataMapping; > > > > /** > > ___ > 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". ___ 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".
Re: [FFmpeg-devel] [PATCH v3 0/4] DOVI: Add NLQ pivots to AVDOVIDataMapping
On 17/06/2022 16.35, quietvoid wrote: The NLQ pivots are not documented but should be present in the header for profile 7 RPU format. It has been verified using Dolby's verification toolkit. With the pivots parsed, the parsed values for num_{x,y}_partitions are correct and usually equal to 1. Changes in v3: - Corrected AVDOVIDataMapping end offset for copy. - Split logging patches and consolidated show_info logging into one call. quietvoid (4): libavutil/dovi_meta: Add nlq_pivots to AVDOVIDataMapping fftools/ffprobe: Add DOVI nlq_pivots logging libavfilter/vf_showinfo: Add DOVI nlq_pivots logging fate: Add test to parse profile 7 DOVI RPU fftools/ffprobe.c | 4 + libavcodec/dovi_rpu.c | 9 +- libavfilter/vf_showinfo.c | 6 + libavutil/dovi_meta.h | 1 + tests/fate/hevc.mak | 3 + tests/ref/fate/hevc-dovi-profile7-rpu | 296 ++ 6 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 tests/ref/fate/hevc-dovi-profile7-rpu Ping on this patch set. ___ 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".
Re: [FFmpeg-devel] [PATCH v3 1/4] libavutil/dovi_meta: Add nlq_pivots to AVDOVIDataMapping
On 10/07/2022 19.12, Andreas Rheinhardt wrote: quietvoid: The NLQ pivots are not documented but should be present in the header for profile 7 RPU format. It has been verified using Dolby's verification toolkit. Signed-off-by: quietvoid --- libavcodec/dovi_rpu.c | 9 - libavutil/dovi_meta.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index a87562c8a3..31e87cfbcc 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -117,7 +117,7 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame) /* Copy only the parts of these structs known to us at compiler-time. */ #define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last)) COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, disable_residual_flag); -COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq[2].linear_deadzone_threshold); +COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots[1]); Do we need the [1] here? I think not. It does indeed seem to be equivalent to just have `nlq_pivots`. COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal); return 0; } @@ -315,7 +315,14 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size) } if (use_nlq) { +int nlq_pivot = 0; vdr->mapping.nlq_method_idc = get_bits(gb, 3); + +for (int i = 0; i < 2; i++) { +nlq_pivot += get_bits(gb, hdr->bl_bit_depth); +vdr->mapping.nlq_pivots[i] = av_clip_uint16(nlq_pivot); +} + /** * The patent mentions another legal value, NLQ_MU_LAW, but it's * not documented anywhere how to parse or apply that type of NLQ. diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h index 3d11e02bff..6afc7b055a 100644 --- a/libavutil/dovi_meta.h +++ b/libavutil/dovi_meta.h @@ -147,6 +147,7 @@ typedef struct AVDOVIDataMapping { uint32_t num_x_partitions; uint32_t num_y_partitions; AVDOVINLQParams nlq[3]; /* per component */ +uint16_t nlq_pivots[2]; /* nlq_pred_pivot_value */ } AVDOVIDataMapping; /** ___ 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". ___ 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".