summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2024-04-28 19:49:43 +0200
committerKacper Michajłow <kasper93@gmail.com>2024-04-29 01:37:02 +0200
commitb68c742b271f6e36d9aedd9fa906a692d267dcd2 (patch)
tree8c5112feb7e5bc630d367814c3a8b2543c23b13a /demux
parent4f828676fd5aa81ded1be596440ab7c978c48be7 (diff)
downloadmpv-b68c742b271f6e36d9aedd9fa906a692d267dcd2.tar.bz2
mpv-b68c742b271f6e36d9aedd9fa906a692d267dcd2.tar.xz
demux/packet: add support for ITU T.35 metadata in Matroska
Diffstat (limited to 'demux')
-rw-r--r--demux/ebml.h3
-rw-r--r--demux/packet.c56
2 files changed, 56 insertions, 3 deletions
diff --git a/demux/ebml.h b/demux/ebml.h
index 86a40092b6..e881731295 100644
--- a/demux/ebml.h
+++ b/demux/ebml.h
@@ -78,6 +78,9 @@ struct ebml_parse_ctx {
#define EBML_UINT_INVALID UINT64_MAX
#define EBML_INT_INVALID INT64_MAX
+/* Block Addition Mappings */
+#define MATROSKA_BLOCK_ADD_ID_TYPE_ITU_T_T35 4
+
bool ebml_is_mkv_level1_id(uint32_t id);
uint32_t ebml_read_id (stream_t *s);
uint64_t ebml_read_length (stream_t *s);
diff --git a/demux/packet.c b/demux/packet.c
index ed43729b87..93f64e844a 100644
--- a/demux/packet.c
+++ b/demux/packet.c
@@ -21,11 +21,13 @@
#include <assert.h>
#include <libavcodec/avcodec.h>
+#include <libavutil/hdr_dynamic_metadata.h>
#include <libavutil/intreadwrite.h>
#include "common/av_common.h"
#include "common/common.h"
#include "demux.h"
+#include "demux/ebml.h"
#include "packet.h"
@@ -232,9 +234,57 @@ int demux_packet_add_blockadditional(struct demux_packet *dp, uint64_t id,
{
if (!dp->avpacket)
return -1;
- uint8_t *sd = av_packet_new_side_data(dp->avpacket,
- AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
- 8 + size);
+
+ switch (id) {
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 5, 100)
+ case MATROSKA_BLOCK_ADD_ID_TYPE_ITU_T_T35: {
+ static const uint8_t ITU_T_T35_COUNTRY_CODE_US = 0xB5;
+ static const uint16_t ITU_T_T35_PROVIDER_CODE_SMTPE = 0x3C;
+
+ if (size < 6)
+ break;
+
+ uint8_t *p = data;
+
+ uint8_t country_code = AV_RB8(p);
+ p += sizeof(country_code);
+ uint16_t provider_code = AV_RB16(p);
+ p += sizeof(provider_code);
+
+ if (country_code != ITU_T_T35_COUNTRY_CODE_US ||
+ provider_code != ITU_T_T35_PROVIDER_CODE_SMTPE)
+ break;
+
+ uint16_t provider_oriented_code = AV_RB16(p);
+ p += sizeof(provider_oriented_code);
+ uint8_t application_identifier = AV_RB8(p);
+ p += sizeof(application_identifier);
+
+ if (provider_oriented_code != 1 || application_identifier != 4)
+ break;
+
+ size_t hdrplus_size;
+ AVDynamicHDRPlus *hdrplus = av_dynamic_hdr_plus_alloc(&hdrplus_size);
+ MP_HANDLE_OOM(hdrplus);
+
+ if (av_dynamic_hdr_plus_from_t35(hdrplus, p, size - (p - (uint8_t *)data)) < 0 ||
+ av_packet_add_side_data(dp->avpacket, AV_PKT_DATA_DYNAMIC_HDR10_PLUS,
+ (uint8_t *)hdrplus, hdrplus_size) < 0)
+ {
+ av_free(hdrplus);
+ return -1;
+ }
+
+ return 0;
+ }
+#endif
+ default:
+ break;
+ }
+
+ uint8_t *sd = av_packet_new_side_data(dp->avpacket,
+ AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
+ 8 + size);
if (!sd)
return -1;
AV_WB64(sd, id);