[FFmpeg-devel] [PATCH] add support for parsing pssh box
Zewu Chen
bjweare at outlook.com
Thu May 17 09:32:09 EEST 2018
Use structure AVEncryptionInitInfo to provide CENC initialization information
for the application.
Signed-off-by: Chen Zewu <bjweare at outlook.com>
---
libavformat/isom.h | 1 +
libavformat/mov.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
diff --git a/libavformat/isom.h b/libavformat/isom.h
index fb36112..f0f5b2c 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -274,6 +274,7 @@ typedef struct MOVContext {
MOVFragmentIndex frag_index;
int atom_depth;
unsigned int aax_mode; ///< 'aax' file has been detected
+ AVEncryptionInitInfo *cenc_init_info;
uint8_t file_key[20];
uint8_t file_iv[20];
void *activation_bytes;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 1975011..f87f10b 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -6165,6 +6165,52 @@ static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ int i, err;
+ int64_t start_pos;
+ uint8_t version = 0;
+ uint32_t num_key_ids = 0;
+ uint32_t data_size = 0;
+
+ if (c->fc->nb_streams < 1)
+ return AVERROR_INVALIDDATA;
+
+ version = avio_r8(pb);
+ avio_skip(pb, 3); /* flags */
+
+ start_pos = avio_tell(pb);
+
+ avio_skip(pb, 16); /* system id */
+
+ if (version > 0) {
+ num_key_ids = avio_rb32(pb);
+ avio_skip(pb, 16*num_key_ids); /* KIDs */
+ }
+
+ data_size = avio_rb32(pb);
+
+ if (c->cenc_init_info)
+ av_log(c->fc, AV_LOG_WARNING, "Duplicated PSSH atom\n");
+ av_free(c->cenc_init_info);
+ c->cenc_init_info = av_encryption_init_info_alloc(16, num_key_ids, 16, data_size);
+ if (!c->cenc_init_info)
+ return AVERROR(ENOMEM);
+
+ avio_seek(pb, start_pos, SEEK_SET);
+ avio_read(pb, c->cenc_init_info->system_id, 16);
+
+ if (version > 0)
+ avio_skip(pb, 4); /* kid_count */
+ for (i = 0; i < num_key_ids; i++)
+ avio_read(pb, c->cenc_init_info->key_ids[i], 16);
+
+ avio_skip(pb, 4); /* data_size */
+ avio_read(pb, c->cenc_init_info->data, data_size);
+
+ return err;
+}
+
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
@@ -6507,6 +6553,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('s','a','i','z'), mov_read_saiz },
{ MKTAG('s','a','i','o'), mov_read_saio },
{ MKTAG('s','c','h','m'), mov_read_schm },
+{ MKTAG('p','s','s','h'), mov_read_pssh },
{ MKTAG('s','c','h','i'), mov_read_default },
{ MKTAG('t','e','n','c'), mov_read_tenc },
{ MKTAG('d','f','L','a'), mov_read_dfla },
@@ -6982,6 +7029,7 @@ static int mov_read_close(AVFormatContext *s)
}
av_freep(&mov->frag_index.item);
+ av_freep(&mov->cenc_init_info);
av_freep(&mov->aes_decrypt);
av_freep(&mov->chapter_tracks);
@@ -7263,6 +7311,22 @@ static int mov_read_header(AVFormatContext *s)
ff_rfps_calculate(s);
+ if (mov->cenc_init_info) {
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ uint8_t *info;
+ size_t info_size;
+
+ info = av_encryption_init_info_add_side_data(mov->cenc_init_info, &info_size);
+ if (!info)
+ return AVERROR(ENOMEM);
+
+ err = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, info, info_size);
+ if (err < 0)
+ break;
+ }
+ }
+
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
MOVStreamContext *sc = st->priv_data;
--
1.9.1
More information about the ffmpeg-devel
mailing list