From: James Almer <jamrial@gmail.com> To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH 6/7] avformat/matroskaenc: support writing Dynamic HDR10+ packet side data Date: Tue, 21 Mar 2023 14:06:36 -0300 Message-ID: <20230321170637.10907-6-jamrial@gmail.com> (raw) In-Reply-To: <20230321170637.10907-1-jamrial@gmail.com> Signed-off-by: James Almer <jamrial@gmail.com> --- libavformat/matroskaenc.c | 90 +++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 13 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 0687d9c32e..b0d088cef5 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -44,6 +44,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/crc.h" #include "libavutil/dict.h" +#include "libavutil/hdr_dynamic_metadata.h" #include "libavutil/intfloat.h" #include "libavutil/intreadwrite.h" #include "libavutil/lfg.h" @@ -1612,6 +1613,10 @@ static void mkv_write_blockadditionmapping(AVFormatContext *s, MatroskaMuxContex // we either write the default value here, or a void element. Either of them will // be overwritten when finishing the track. put_ebml_uint(mkv->track.bc, MATROSKA_ID_TRACKMAXBLKADDID, 0); + // Similarly, reserve space for an eventual HDR10+ ITU T.35 metadata BlockAdditionMapping. + put_ebml_void(pb, 3 /* BlockAdditionMapping */ + + 4 /* BlockAddIDValue */ + + 4 /* BlockAddIDType */); } if (dovi && dovi->dv_profile <= 10) { @@ -2618,17 +2623,34 @@ static int webm_reformat_vtt(MatroskaMuxContext *mkv, AVIOContext *pb, return 0; } +static void mkv_write_blockadditional(EbmlWriter *writer, const uint8_t *buf, + size_t size, enum AVPacketSideDataType type, + uint64_t additional_id) +{ + size_t offset = 0; + + if (type == AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL) + offset = 8; + + ebml_writer_open_master(writer, MATROSKA_ID_BLOCKMORE); + ebml_writer_add_uint(writer, MATROSKA_ID_BLOCKADDID, additional_id); + ebml_writer_add_bin (writer, MATROSKA_ID_BLOCKADDITIONAL, + buf + offset, size - offset); + ebml_writer_close_master(writer); +} + static int mkv_write_block(void *logctx, MatroskaMuxContext *mkv, AVIOContext *pb, const AVCodecParameters *par, mkv_track *track, const AVPacket *pkt, int keyframe, int64_t ts, uint64_t duration, int force_blockgroup, int64_t relative_packet_pos) { - uint8_t *side_data; + uint8_t *side_data, *buf = NULL; size_t side_data_size; - uint64_t additional_id; + uint64_t additional_id, max_blockaddid = 0; unsigned track_number = track->track_num; - EBML_WRITER(9); + int ret; + EBML_WRITER(13); mkv->cur_block.track = track; mkv->cur_block.pkt = pkt; @@ -2670,17 +2692,50 @@ static int mkv_write_block(void *logctx, MatroskaMuxContext *mkv, // Only the Codec-specific BlockMore (id == 1) is currently supported. (additional_id = AV_RB64(side_data)) == 1) { ebml_writer_open_master(&writer, MATROSKA_ID_BLOCKADDITIONS); - ebml_writer_open_master(&writer, MATROSKA_ID_BLOCKMORE); - /* Until dbc50f8a our demuxer used a wrong default value - * of BlockAddID, so we write it unconditionally. */ - ebml_writer_add_uint(&writer, MATROSKA_ID_BLOCKADDID, additional_id); - ebml_writer_add_bin (&writer, MATROSKA_ID_BLOCKADDITIONAL, - side_data + 8, side_data_size - 8); - ebml_writer_close_master(&writer); - ebml_writer_close_master(&writer); - track->max_blockaddid = additional_id; + mkv_write_blockadditional(&writer, side_data, side_data_size, + AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, + additional_id); + max_blockaddid = track->max_blockaddid = FFMAX(track->max_blockaddid, + additional_id); + } + + side_data = av_packet_get_side_data(pkt, + AV_PKT_DATA_DYNAMIC_HDR10_PLUS, + &side_data_size); + if (side_data_size) { + uint8_t *payload; + size_t payload_size, buf_size; + int ret = av_dynamic_hdr_plus_to_t35((AVDynamicHDRPlus *)side_data, &payload, + &payload_size); + if (ret < 0) + return ret; + + buf_size = payload_size + 6; + buf = av_malloc(buf_size); + if (!buf) { + av_free(payload); + return AVERROR(ENOMEM); + } + + AV_WB8 (buf + 0, 0xB5); // country_code + AV_WB16(buf + 1, 0x3C); // provider_code + AV_WB16(buf + 3, 0x01); // provider_oriented_code + AV_WB8 (buf + 5, 0x04); // application_identifier + memcpy(buf + 6, payload, payload_size); + + if (!max_blockaddid) + ebml_writer_open_master(&writer, MATROSKA_ID_BLOCKADDITIONS); + mkv_write_blockadditional(&writer, buf, buf_size, + AV_PKT_DATA_DYNAMIC_HDR10_PLUS, + 4); + track->max_blockaddid = FFMAX(track->max_blockaddid, 4); + + av_free(payload); } + if (max_blockaddid) + ebml_writer_close_master(&writer); + if (!force_blockgroup && writer.nb_elements == 2) { /* Nothing except the BlockGroup + Block. Can use a SimpleBlock. */ writer.elements++; // Skip the BlockGroup. @@ -2693,7 +2748,10 @@ static int mkv_write_block(void *logctx, MatroskaMuxContext *mkv, ebml_writer_add_sint(&writer, MATROSKA_ID_BLOCKREFERENCE, track->last_timestamp - ts); - return ebml_writer_write(&writer, pb); + ret = ebml_writer_write(&writer, pb); + av_free(buf); + + return ret; } static int mkv_end_cluster(AVFormatContext *s) @@ -3095,6 +3153,12 @@ after_cues: avio_seek(mkv->track.bc, track->blockadditionmapping_offset, SEEK_SET); put_ebml_uint(mkv->track.bc, MATROSKA_ID_TRACKMAXBLKADDID, track->max_blockaddid); + if (track->max_blockaddid == 4) { // HDR10+ + ebml_master mapping_master = start_ebml_master(mkv->track.bc, MATROSKA_ID_TRACKBLKADDMAPPING, 8); + put_ebml_uint(mkv->track.bc, MATROSKA_ID_BLKADDIDTYPE, MATROSKA_BLOCK_ADD_ID_TYPE_ITU_T_T35); + put_ebml_uint(mkv->track.bc, MATROSKA_ID_BLKADDIDVALUE, 4); + end_ebml_master(mkv->track.bc, mapping_master); + } } avio_seek(mkv->track.bc, end, SEEK_SET); -- 2.40.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-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2023-03-21 17:07 UTC|newest] Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-03-21 17:06 [FFmpeg-devel] [PATCH 1/7] avformat/matroskadec: support parsing more than one BlockMore element James Almer 2023-03-21 17:06 ` [FFmpeg-devel] [PATCH 2/7] avformat/matroskadec: set the default value for BlockAddIDType James Almer 2023-03-21 17:06 ` [FFmpeg-devel] [PATCH 3/7] avformat/matroskadec: export Dynamic HDR10+ packet side data James Almer 2023-03-24 11:18 ` Anton Khirnov 2023-03-24 11:28 ` James Almer 2023-03-24 11:40 ` Anton Khirnov 2023-03-24 12:34 ` James Almer 2023-03-21 17:06 ` [FFmpeg-devel] [PATCH 4/7] avformat/matroska: add a few more Block Addition ID Type enum values James Almer 2023-03-21 17:06 ` [FFmpeg-devel] [PATCH 5/7] avformat/matroskaenc: write a MaxBlockAdditionID element James Almer 2023-03-21 17:59 ` [FFmpeg-devel] [PATCH v2 " James Almer 2023-03-24 11:37 ` [FFmpeg-devel] [PATCH " Anton Khirnov 2023-03-24 11:41 ` James Almer 2023-03-24 11:43 ` Anton Khirnov 2023-03-21 17:06 ` James Almer [this message] 2023-03-21 18:00 ` [FFmpeg-devel] [PATCH v2 6/7] avformat/matroskaenc: support writing Dynamic HDR10+ packet side data James Almer 2023-03-24 11:45 ` Anton Khirnov 2023-03-24 11:50 ` James Almer 2023-03-24 11:58 ` Anton Khirnov 2023-03-24 12:59 ` James Almer 2023-03-24 15:11 ` Jerome Martinez 2023-03-24 15:39 ` James Almer 2023-03-21 17:06 ` [FFmpeg-devel] [PATCH 7/7] fate/matroska: add HDR10+ muxing tests James Almer 2023-03-21 18:00 ` [FFmpeg-devel] [PATCH v2 " James Almer
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230321170637.10907-6-jamrial@gmail.com \ --to=jamrial@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git