> 2020年4月30日 下午9:10,Yaroslav Pogrebnyak <yyyaros...@gmail.com> 写道: > > This patch adds possibility to use 'periodic-rekey' option with > multi-variant streams to hlsenc muxer. All streams variants > use parameters from the same key_info_file. > > There are 2 sets of encryption options that kind of overlaps and add > complexity, so I tried to do the thing without changing too much code. > > There is a little duplication of the key_file, key_uri, iv_string, etc > in the VariantStream since we copy it from hls to each variant stream, > but generally all the code remains the same to minimise appearing > of unexpected bugs. Refactoring could be done as a separate patch then as > needed. > > Signed-off-by: Yaroslav Pogrebnyak <yyyaros...@gmail.com> > > --- > libavformat/hlsenc.c | 81 ++++++++++++++++++++++++-------------------- > 1 file changed, 44 insertions(+), 37 deletions(-) > > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c > index d75684741f..1522eb5218 100644 > --- a/libavformat/hlsenc.c > +++ b/libavformat/hlsenc.c > @@ -157,6 +157,13 @@ typedef struct VariantStream { > char *fmp4_init_filename; > char *base_output_dirname; > > + int encrypt_started; > + > + char key_file[LINE_BUFFER_SIZE + 1]; > + char key_uri[LINE_BUFFER_SIZE + 1]; > + char key_string[KEYSIZE*2 + 1]; > + char iv_string[KEYSIZE*2 + 1]; > + > AVStream **streams; > char codec_attr[128]; > CodecAttributeStatus attr_status; > @@ -705,7 +712,7 @@ static int do_encrypt(AVFormatContext *s, VariantStream > *vs) > } > > > -static int hls_encryption_start(AVFormatContext *s) > +static int hls_encryption_start(AVFormatContext *s, VariantStream *vs) > { > HLSContext *hls = s->priv_data; > int ret; > @@ -722,44 +729,44 @@ static int hls_encryption_start(AVFormatContext *s) > return ret; > } > > - ff_get_line(pb, hls->key_uri, sizeof(hls->key_uri)); > - hls->key_uri[strcspn(hls->key_uri, "\r\n")] = '\0'; > + ff_get_line(pb, vs->key_uri, sizeof(vs->key_uri)); > + vs->key_uri[strcspn(vs->key_uri, "\r\n")] = '\0'; > > - ff_get_line(pb, hls->key_file, sizeof(hls->key_file)); > - hls->key_file[strcspn(hls->key_file, "\r\n")] = '\0'; > + ff_get_line(pb, vs->key_file, sizeof(vs->key_file)); > + vs->key_file[strcspn(vs->key_file, "\r\n")] = '\0'; > > - ff_get_line(pb, hls->iv_string, sizeof(hls->iv_string)); > - hls->iv_string[strcspn(hls->iv_string, "\r\n")] = '\0'; > + ff_get_line(pb, vs->iv_string, sizeof(vs->iv_string)); > + vs->iv_string[strcspn(vs->iv_string, "\r\n")] = '\0'; > > ff_format_io_close(s, &pb); > > - if (!*hls->key_uri) { > + if (!*vs->key_uri) { > av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n"); > return AVERROR(EINVAL); > } > > - if (!*hls->key_file) { > + if (!*vs->key_file) { > av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n"); > return AVERROR(EINVAL); > } > > set_http_options(s, &options, hls); > - ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_READ, &options); > + ret = s->io_open(s, &pb, vs->key_file, AVIO_FLAG_READ, &options); > av_dict_free(&options); > if (ret < 0) { > - av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", > hls->key_file); > + av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", > vs->key_file); > return ret; > } > > ret = avio_read(pb, key, sizeof(key)); > ff_format_io_close(s, &pb); > if (ret != sizeof(key)) { > - av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", > hls->key_file); > + av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", > vs->key_file); > if (ret >= 0 || ret == AVERROR_EOF) > ret = AVERROR(EINVAL); > return ret; > } > - ff_data_to_hex(hls->key_string, key, sizeof(key), 0); > + ff_data_to_hex(vs->key_string, key, sizeof(key), 0); > > return 0; > } > @@ -1081,8 +1088,8 @@ static int hls_append_segment(struct AVFormatContext > *s, HLSContext *hls, > } > > if (hls->key_info_file || hls->encrypt) { > - av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri)); > - av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string)); > + av_strlcpy(en->key_uri, vs->key_uri, sizeof(en->key_uri)); > + av_strlcpy(en->iv_string, vs->iv_string, sizeof(en->iv_string)); > } > > if (!vs->segments) > @@ -1170,9 +1177,9 @@ static int parse_playlist(AVFormatContext *s, const > char *url, VariantStream *vs > ptr += strlen("URI=\""); > end = av_stristr(ptr, ","); > if (end) { > - av_strlcpy(hls->key_uri, ptr, end - ptr); > + av_strlcpy(vs->key_uri, ptr, end - ptr); > } else { > - av_strlcpy(hls->key_uri, ptr, sizeof(hls->key_uri)); > + av_strlcpy(vs->key_uri, ptr, sizeof(vs->key_uri)); > } > } > > @@ -1181,9 +1188,9 @@ static int parse_playlist(AVFormatContext *s, const > char *url, VariantStream *vs > ptr += strlen("IV=0x"); > end = av_stristr(ptr, ","); > if (end) { > - av_strlcpy(hls->iv_string, ptr, end - ptr); > + av_strlcpy(vs->iv_string, ptr, end - ptr); > } else { > - av_strlcpy(hls->iv_string, ptr, sizeof(hls->iv_string)); > + av_strlcpy(vs->iv_string, ptr, sizeof(vs->iv_string)); > } > } > > @@ -1692,21 +1699,27 @@ static int hls_start(AVFormatContext *s, > VariantStream *vs) > " ignoring -hls_enc\n"); > } > > - if (!c->encrypt_started || (c->flags & HLS_PERIODIC_REKEY)) { > + if (!vs->encrypt_started || (c->flags & HLS_PERIODIC_REKEY)) { > if (c->key_info_file) { > - if ((err = hls_encryption_start(s)) < 0) > + if ((err = hls_encryption_start(s, vs)) < 0) > goto fail; > } else { > - if ((err = do_encrypt(s, vs)) < 0) > - goto fail; > + if (!c->encrypt_started) { > + if ((err = do_encrypt(s, vs)) < 0) > + goto fail; > + c->encrypt_started = 1; > + } > + av_strlcpy(vs->key_uri, c->key_uri, sizeof(vs->key_uri)); > + av_strlcpy(vs->key_string, c->key_string, > sizeof(vs->key_string)); > + av_strlcpy(vs->iv_string, c->iv_string, > sizeof(vs->iv_string)); > } > - c->encrypt_started = 1; > + vs->encrypt_started = 1; > } > - err = av_strlcpy(iv_string, c->iv_string, sizeof(iv_string)); > + err = av_strlcpy(iv_string, vs->iv_string, sizeof(iv_string)); > if (!err) { > snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, > vs->sequence); > - memset(c->iv_string, 0, sizeof(c->iv_string)); > - memcpy(c->iv_string, iv_string, sizeof(iv_string)); > + memset(vs->iv_string, 0, sizeof(vs->iv_string)); > + memcpy(vs->iv_string, iv_string, sizeof(iv_string)); > } > } > if (c->segment_type != SEGMENT_TYPE_FMP4) { > @@ -2403,8 +2416,8 @@ static int hls_write_packet(AVFormatContext *s, > AVPacket *pkt) > AVDictionary *options = NULL; > char *filename = NULL; > if (hls->key_info_file || hls->encrypt) { > - av_dict_set(&options, "encryption_key", hls->key_string, > 0); > - av_dict_set(&options, "encryption_iv", hls->iv_string, > 0); > + av_dict_set(&options, "encryption_key", vs->key_string, > 0); > + av_dict_set(&options, "encryption_iv", vs->iv_string, 0); > filename = av_asprintf("crypto:%s", oc->url); > } else { > filename = av_asprintf("%s", oc->url); > @@ -2595,8 +2608,8 @@ static int hls_write_trailer(struct AVFormatContext *s) > return AVERROR(ENOMEM); > } > if (hls->key_info_file || hls->encrypt) { > - av_dict_set(&options, "encryption_key", hls->key_string, 0); > - av_dict_set(&options, "encryption_iv", hls->iv_string, 0); > + av_dict_set(&options, "encryption_key", vs->key_string, 0); > + av_dict_set(&options, "encryption_iv", vs->iv_string, 0); > filename = av_asprintf("crypto:%s", oc->url); > } else { > filename = av_asprintf("%s", oc->url); > @@ -2742,12 +2755,6 @@ static int hls_init(AVFormatContext *s) > ret); > goto fail; > } > - //TODO: Updates needed to encryption functionality with periodic re-key > when more than one variant streams are present > - if (hls->nb_varstreams > 1 && hls->flags & HLS_PERIODIC_REKEY) { > - ret = AVERROR(EINVAL); > - av_log(s, AV_LOG_ERROR, "Periodic re-key not supported when more > than one variant streams are present\n"); > - goto fail; > - } > > if (!hls->method && http_base_proto) { > av_log(hls, AV_LOG_WARNING, "No HTTP method set, hls muxer defaulting > to method PUT.\n"); > -- > 2.17.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
LGTM Thanks Steven Liu _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".