[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