Message ID | PS1PR03MB1868E5CEC51DAE8E44C6A09EB0910@PS1PR03MB1868.apcprd03.prod.outlook.com |
---|---|
State | New |
Headers | show |
On Wed, May 16, 2018 at 11:32 PM, Zewu Chen <bjweare@outlook.com> wrote: > Use structure AVEncryptionInitInfo to provide CENC initialization information > for the application. > > Signed-off-by: Chen Zewu <bjweare@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 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel MP4 can have multiple PSSH boxes in it, so this would depend on http://ffmpeg.org/pipermail/ffmpeg-devel/2018-May/229665.html I also have implemented this with multiple PSSH support as well as exposing the AVEncryptionInfo, but I am waiting on that patch to be merged. I sent a first version that only supported one PSSH box in it in January, with no movement on it.
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;
Use structure AVEncryptionInitInfo to provide CENC initialization information for the application. Signed-off-by: Chen Zewu <bjweare@outlook.com> --- libavformat/isom.h | 1 + libavformat/mov.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+)