[FFmpeg-devel] [PATCH] pssh: add a flag for writing pssh boxes
Malek Assaad
malek.m000a at gmail.com
Fri Aug 11 10:37:44 EEST 2023
Hi all,
I would like to add an option to create pssh boxes with ffmpeg. I have
included my implementation for review. I consulted the standard: ISO/IEC
23001-7:2022 and I am looking forward for the feedback.
Add a flag to create Protection System Specific Header boxes in a
movie box in coherence with ISO/IEC 23001-7:2022.
Signed-off-by: Malek Assaad <malek.m000a at gmail.com>
---
libavformat/movenc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++
libavformat/movenc.h | 1 +
2 files changed, 47 insertions(+)
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index f1cc80b1b3..8953f8362b 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -94,6 +94,7 @@ static const AVOption options[] = {
{ "write_gama", "Write deprecated gama atom", 0,
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX,
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "use_metadata_tags", "Use mdta atom for metadata.", 0,
AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX,
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "skip_trailer", "Skip writing the mfra/tfra/mfro trailer for
fragmented files", 0, AV_OPT_TYPE_CONST, {.i64 =
FF_MOV_FLAG_SKIP_TRAILER}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM,
"movflags" },
+ { "write_pssh", "Write pssh atom", 0, AV_OPT_TYPE_CONST, {.i64 =
FF_MOV_FLAG_PSSH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM,
"movflags"},
{ "negative_cts_offsets", "Use negative CTS offsets (reducing the
need for edit lists)", 0, AV_OPT_TYPE_CONST, {.i64 =
FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS}, INT_MIN, INT_MAX,
AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
{ "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext,
iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
@@ -4506,6 +4507,45 @@ static int mov_write_uuidusmt_tag(AVIOContext
*pb, AVFormatContext *s)
return 0;
}
+static int mov_write_pssh_tag(AVIOContext *pb, MOVMuxContext *mov,
AVStream *st)
+{
+ size_t side_data_size;
+ int i, j;
+ int64_t pos;
+ AVEncryptionInitInfo *info;
+ uint8_t *side_data = av_stream_get_side_data(st,
+
AV_PKT_DATA_ENCRYPTION_INIT_INFO,
+ &side_data_size);
+ info = av_encryption_init_info_get_side_data(side_data,
side_data_size);
+
+ for(AVEncryptionInitInfo *copy = info; copy; copy = copy->next) {
+ if (!copy->data_size && !copy->num_key_ids)
+ continue;
+
+ pos = avio_tell(pb);
+ avio_wb32(pb, 0); /* size placeholder */
+ ffio_wfourcc(pb, "pssh");
+ avio_w8(pb, 1); /* version */
+ avio_wb24(pb, 0);
+ for (i = 0; i < copy->system_id_size; i++) {
+ avio_w8(pb, copy->system_id[i]);
+ }
+ avio_wb32(pb, copy->num_key_ids);
+ for (i = 0; i < copy->num_key_ids; i++) {
+ for (j = 0; j < copy->key_id_size; j++) {
+ avio_w8(pb, copy->key_ids[i][j]);
+ }
+ }
+ avio_wb32(pb, copy->data_size);
+ for (i = 0; i < copy->data_size; i++) {
+ avio_w8(pb, copy->data[i]);
+ }
+ update_size(pb, pos);
+ }
+
+ return 0;
+}
+
static void build_chunks(MOVTrack *trk)
{
int i;
@@ -4650,6 +4690,12 @@ static int mov_write_moov_tag(AVIOContext *pb,
MOVMuxContext *mov,
else if (mov->mode != MODE_AVIF)
mov_write_udta_tag(pb, mov, s);
+ if (mov->flags & FF_MOV_FLAG_PSSH) {
+ for (i = 0; i < mov->nb_streams; i++) {
+ mov_write_pssh_tag(pb, mov, s->streams[i]);
+ }
+ }
+
return update_size(pb, pos);
}
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index e85d83abdb..76f81bcbfd 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -276,6 +276,7 @@ typedef struct MOVMuxContext {
#define FF_MOV_FLAG_SKIP_SIDX (1 << 21)
#define FF_MOV_FLAG_CMAF (1 << 22)
#define FF_MOV_FLAG_PREFER_ICC (1 << 23)
+#define FF_MOV_FLAG_PSSH (1 << 24)
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
-- 2.30.2
More information about the ffmpeg-devel
mailing list