From 805886e76fe7123cd633ab564c7fc8cf932aba3a Mon Sep 17 00:00:00 2001
From: Evgeny <kea@obninsk.ru>
Date: Fri, 16 Nov 2018 12:39:32 +0300
Subject: [PATCH 4/6] Application should have read PSSH data for license
request
Example:
for (int i=0; i < ctx->nb_streams; i++) {
AVStream* avs = ctx->streams[i];
if (avs->nb_side_data) {
AVPacketSideData* sd = avs->side_data;
if (sd->type == AV_PKT_DATA_ENCRYPTION_INIT_INFO) {
licenseRequest(sd->data, sd->size);
break;
}
}
TODO: out of band PSSH (from manifest)
---
libavformat/dashdec.c | 19 +++++++++++++++++++
libavformat/hls.c | 25 ++++++++++++++++++++++---
2 files changed, 41 insertions(+), 3 deletions(-)
@@ -1906,6 +1906,25 @@ static int open_demux_for_component(AVFormatContext *s, struct representation *p
st->id = i;
avcodec_parameters_copy(st->codecpar, pls->ctx->streams[i]->codecpar);
avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
+
+ /* Copy side data if present */
+ if (ist->nb_side_data) {
+ st->side_data = av_mallocz_array(ist->nb_side_data,
+ sizeof(AVPacketSideData));
+ if (!st->side_data)
+ return AVERROR(ENOMEM);
+ st->nb_side_data = ist->nb_side_data;
+
+ for (int i = 0; i < ist->nb_side_data; i++) {
+ uint8_t *data = av_memdup(ist->side_data[i].data,
+ ist->side_data[i].size);
+ if (!data)
+ return AVERROR(ENOMEM);
+ st->side_data[i].type = ist->side_data[i].type;
+ st->side_data[i].size = ist->side_data[i].size;
+ st->side_data[i].data = data;
+ }
+ }
}
return 0;
@@ -1229,9 +1229,9 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg,
}
ret = 0;
} else if (seg->key_type == KEY_SAMPLE_AES) {
- av_log(pls->parent, AV_LOG_ERROR,
- "SAMPLE-AES encryption is not supported yet\n");
- ret = AVERROR_PATCHWELCOME;
+ av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
+ av_dict_set(&opts, "pssh", pls->key_url, 0);
+ ret = open_url(pls->parent, in, seg->url, c->avio_opts, opts, &is_http);
}
else
ret = AVERROR(ENOSYS);
@@ -1737,6 +1737,25 @@ static int update_streams_from_subdemuxer(AVFormatContext *s, struct playlist *p
err = set_stream_info_from_input_stream(st, pls, ist);
if (err < 0)
return err;
+
+ /* Copy side data if present */
+ if (ist->nb_side_data) {
+ st->side_data = av_mallocz_array(ist->nb_side_data,
+ sizeof(AVPacketSideData));
+ if (!st->side_data)
+ return AVERROR(ENOMEM);
+ st->nb_side_data = ist->nb_side_data;
+
+ for (int i = 0; i < ist->nb_side_data; i++) {
+ uint8_t *data = av_memdup(ist->side_data[i].data,
+ ist->side_data[i].size);
+ if (!data)
+ return AVERROR(ENOMEM);
+ st->side_data[i].type = ist->side_data[i].type;
+ st->side_data[i].size = ist->side_data[i].size;
+ st->side_data[i].data = data;
+ }
+ }
}
return 0;
--
2.1.4