[FFmpeg-devel] [PATCH 4/4] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 0feddb06e4..3c34d69538 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2051,23 +2051,23 @@ static int hls_read_header(AVFormatContext *s) if (in_fmt->raw_codec_id == pls->audio_setup_info.codec_id) break; } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +return ret; +} av_free(url); -return ret; -} -av_free(url); } if (seg && seg->key_type == KEY_SAMPLE_AES) { @@ -2121,7 +2121,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) ret = ff_hls_senc_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); else -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) return ret; -- 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".
[FFmpeg-devel] [PATCH 3/4] libavformat/hls: add support for decryption of HLS media segments encrypted using SAMPLE-AES encryption method
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile| 2 +- libavformat/hls.c | 128 +++-- libavformat/hls_sample_encryption.c | 389 libavformat/hls_sample_encryption.h | 65 + libavformat/mpegts.c| 11 + 5 files changed, 576 insertions(+), 19 deletions(-) create mode 100644 libavformat/hls_sample_encryption.c create mode 100644 libavformat/hls_sample_encryption.h diff --git a/libavformat/Makefile b/libavformat/Makefile index f7e47563da..53139663cc 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -238,7 +238,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_encryption.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 421a60a476..0feddb06e4 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_encryption.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -214,6 +219,7 @@ typedef struct HLSContext { int http_multiple; int http_seekable; AVIOContext *playlist_pb; +HLSCryptoContext crypto_ctx; } HLSContext; static void free_segment_dynarray(struct segment **segments, int n_segments) @@ -1006,7 +1012,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int64_t n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1035,17 +1044,18 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); for (meta = *extra_meta; meta; meta = meta->next) { if (!strcmp(meta->tag, "PRIV")) { ID3v2ExtraMetaPRIV *priv = &meta->data.priv; -if (priv->datasize == 8 && !strcmp(priv->owner, id3_priv_owner_ts)) { +if (priv->datasize == 8 && !av_strncasecmp(priv->owner, id3_priv_owner_ts, 44)) { /* 33-bit MPEG timestamp */ int64_t ts = AV_RB64(priv->data); av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts); @@ -1053,6 +1063,8 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, *dts = ts; else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); +} else if (priv->datasize >= 8 && !av_strncasecmp(priv->owner, id3_priv_owner_audio_setup, 36)) { +ff_hls_senc_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); } } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; @@ -1096,7 +1108,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE
[FFmpeg-devel] [PATCH 2/4] libavformat/mov: add support for 'cens', 'cbc1' and 'cbcs' encryption schemes specified in Common Encryption (CENC) standard
correct implementation of 'cenc' encryption scheme to support decryption of partial cipher blocks at the end of subsamples https://www.iso.org/standard/68042.html Signed-off-by: Nachiket Tarate --- libavformat/isom.h | 2 + libavformat/mov.c | 245 +++-- 2 files changed, 241 insertions(+), 6 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 34a58c79b7..b484250034 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -237,6 +237,8 @@ typedef struct MOVStreamContext { int has_sidx; // If there is an sidx entry for this stream. struct { struct AVAESCTR* aes_ctr; +struct AVAES *aes_ctx; +unsigned int frag_index_entry_base; unsigned int per_sample_iv_size; // Either 0, 8, or 16. AVEncryptionInfo *default_encrypted_sample; MOVEncryptionIndex *encryption_index; diff --git a/libavformat/mov.c b/libavformat/mov.c index 4bc42d6b20..81312f1371 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6584,15 +6584,149 @@ static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } -static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) { int i, ret; +int bytes_of_protected_data; +int partially_encrypted_block_size; +uint8_t *partially_encrypted_block; +uint8_t block[16]; -if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) { -av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n"); -return AVERROR_PATCHWELCOME; +if (!sc->cenc.aes_ctr) { +/* initialize the cipher */ +sc->cenc.aes_ctr = av_aes_ctr_alloc(); +if (!sc->cenc.aes_ctr) { +return AVERROR(ENOMEM); +} + +ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key); +if (ret < 0) { +return ret; +} +} + +av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv); + +if (!sample->subsample_count) { +/* decrypt the whole packet */ +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size); +return 0; +} + +partially_encrypted_block_size = 0; + +for (i = 0; i < sample->subsample_count; i++) { +if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { +av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); +return AVERROR_INVALIDDATA; +} + +/* skip the clear bytes */ +input += sample->subsamples[i].bytes_of_clear_data; +size -= sample->subsamples[i].bytes_of_clear_data; + +/* decrypt the encrypted bytes */ + +if (partially_encrypted_block_size) { +memcpy(block, partially_encrypted_block, partially_encrypted_block_size); +memcpy(block+partially_encrypted_block_size, input, 16-partially_encrypted_block_size); +av_aes_ctr_crypt(sc->cenc.aes_ctr, block, block, 16); +memcpy(partially_encrypted_block, block, partially_encrypted_block_size); +memcpy(input, block+partially_encrypted_block_size, 16-partially_encrypted_block_size); +input += 16-partially_encrypted_block_size; +size -= 16-partially_encrypted_block_size; +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data - (16-partially_encrypted_block_size); +} else { +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data; +} + +if (i < sample->subsample_count-1) { +int num_of_encrypted_blocks = bytes_of_protected_data/16; +partially_encrypted_block_size = bytes_of_protected_data%16; +if (partially_encrypted_block_size) +partially_encrypted_block = input + 16*num_of_encrypted_blocks; +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, 16*num_of_encrypted_blocks); +} else { +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data); +} + +input += bytes_of_protected_data; +size -= bytes_of_protected_data; +} + +if (size > 0) { +av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n"); +return AVERROR_INVALIDDATA; +} + +return 0; +} + +static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +{ +int i, ret; +int num_of_encrypted_blocks; +uint8_t iv[16]
[FFmpeg-devel] [PATCH 1/4] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of sample decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 15 +++ libavcodec/adts_parser.c | 31 +++ 3 files changed, 47 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..e4454529c4 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..354d07e1f8 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,18 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. After using the header + * information, the allocated memory must be freed by using av_free. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..4a1a8fd5f4 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,34 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (!phdr || !buf || size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) { +av_freep(phdr); +return ret; +} + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) { +av_freep(phdr); +return ret; +} + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 4/4] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 0feddb06e4..3c34d69538 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2051,23 +2051,23 @@ static int hls_read_header(AVFormatContext *s) if (in_fmt->raw_codec_id == pls->audio_setup_info.codec_id) break; } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +return ret; +} av_free(url); -return ret; -} -av_free(url); } if (seg && seg->key_type == KEY_SAMPLE_AES) { @@ -2121,7 +2121,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) ret = ff_hls_senc_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); else -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) return ret; -- 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".
[FFmpeg-devel] [PATCH 3/4] libavformat/hls: add support for decryption of HLS media segments encrypted using SAMPLE-AES encryption method
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile| 2 +- libavformat/hls.c | 128 +++-- libavformat/hls_sample_encryption.c | 389 libavformat/hls_sample_encryption.h | 65 + libavformat/mpegts.c| 11 + 5 files changed, 576 insertions(+), 19 deletions(-) create mode 100644 libavformat/hls_sample_encryption.c create mode 100644 libavformat/hls_sample_encryption.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 7e0f587b41..6130424161 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -238,7 +238,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_encryption.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 421a60a476..0feddb06e4 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_encryption.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -214,6 +219,7 @@ typedef struct HLSContext { int http_multiple; int http_seekable; AVIOContext *playlist_pb; +HLSCryptoContext crypto_ctx; } HLSContext; static void free_segment_dynarray(struct segment **segments, int n_segments) @@ -1006,7 +1012,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int64_t n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1035,17 +1044,18 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); for (meta = *extra_meta; meta; meta = meta->next) { if (!strcmp(meta->tag, "PRIV")) { ID3v2ExtraMetaPRIV *priv = &meta->data.priv; -if (priv->datasize == 8 && !strcmp(priv->owner, id3_priv_owner_ts)) { +if (priv->datasize == 8 && !av_strncasecmp(priv->owner, id3_priv_owner_ts, 44)) { /* 33-bit MPEG timestamp */ int64_t ts = AV_RB64(priv->data); av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts); @@ -1053,6 +1063,8 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, *dts = ts; else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); +} else if (priv->datasize >= 8 && !av_strncasecmp(priv->owner, id3_priv_owner_audio_setup, 36)) { +ff_hls_senc_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); } } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; @@ -1096,7 +1108,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE
[FFmpeg-devel] [PATCH 2/4] libavformat/mov: add support for 'cens', 'cbc1' and 'cbcs' encryption schemes specified in Common Encryption (CENC) standard
correct implementation of 'cenc' encryption scheme to support decryption of partial cipher blocks at the end of subsamples https://www.iso.org/standard/68042.html Signed-off-by: Nachiket Tarate --- libavformat/isom.h | 2 + libavformat/mov.c | 246 +++-- 2 files changed, 242 insertions(+), 6 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 34a58c79b7..b484250034 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -237,6 +237,8 @@ typedef struct MOVStreamContext { int has_sidx; // If there is an sidx entry for this stream. struct { struct AVAESCTR* aes_ctr; +struct AVAES *aes_ctx; +unsigned int frag_index_entry_base; unsigned int per_sample_iv_size; // Either 0, 8, or 16. AVEncryptionInfo *default_encrypted_sample; MOVEncryptionIndex *encryption_index; diff --git a/libavformat/mov.c b/libavformat/mov.c index c5583e07c7..2b6cac102f 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6579,15 +6579,150 @@ static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } -static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) { int i, ret; +int bytes_of_protected_data; +int partially_encrypted_block_size; +uint8_t *partially_encrypted_block; +uint8_t block[16]; -if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) { -av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n"); -return AVERROR_PATCHWELCOME; +if (!sc->cenc.aes_ctr) { +/* initialize the cipher */ +sc->cenc.aes_ctr = av_aes_ctr_alloc(); +if (!sc->cenc.aes_ctr) { +return AVERROR(ENOMEM); +} + +ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key); +if (ret < 0) { +return ret; +} +} + +av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv); + +if (!sample->subsample_count) { +/* decrypt the whole packet */ +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size); +return 0; +} + +partially_encrypted_block_size = 0; + +for (i = 0; i < sample->subsample_count; i++) { +if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { +av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); +return AVERROR_INVALIDDATA; +} + +/* skip the clear bytes */ +input += sample->subsamples[i].bytes_of_clear_data; +size -= sample->subsamples[i].bytes_of_clear_data; + +/* decrypt the encrypted bytes */ + +if (partially_encrypted_block_size != 0) +{ +memcpy(block, partially_encrypted_block, partially_encrypted_block_size); +memcpy(block+partially_encrypted_block_size, input, 16-partially_encrypted_block_size); +av_aes_ctr_crypt(sc->cenc.aes_ctr, block, block, 16); +memcpy(partially_encrypted_block, block, partially_encrypted_block_size); +memcpy(input, block+partially_encrypted_block_size, 16-partially_encrypted_block_size); +input += 16-partially_encrypted_block_size; +size -= 16-partially_encrypted_block_size; +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data - (16-partially_encrypted_block_size); +} else { +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data; +} + +if (i < sample->subsample_count-1) { +int num_of_encrypted_blocks = bytes_of_protected_data/16; +partially_encrypted_block_size = bytes_of_protected_data%16; +if (partially_encrypted_block_size != 0) +partially_encrypted_block = input + 16*num_of_encrypted_blocks; +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, 16*num_of_encrypted_blocks); +} else { +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data); +} + +input += bytes_of_protected_data; +size -= bytes_of_protected_data; +} + +if (size > 0) { +av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n"); +return AVERROR_INVALIDDATA; +} + +return 0; +} + +static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +{ +int i, ret; +int num_of_encrypted_blocks; +uint8_t iv[16]
[FFmpeg-devel] [PATCH 1/4] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of sample decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 15 +++ libavcodec/adts_parser.c | 31 +++ 3 files changed, 47 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..e4454529c4 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..166a28ffc9 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,18 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. After using the header + * information, the allocated memory must be freed by using av_free(). + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..4a1a8fd5f4 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,34 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (!phdr || !buf || size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) { +av_freep(phdr); +return ret; +} + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) { +av_freep(phdr); +return ret; +} + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 4/4] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 022dae0391..7e457281f4 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2051,23 +2051,23 @@ static int hls_read_header(AVFormatContext *s) if (in_fmt->raw_codec_id == pls->audio_setup_info.codec_id) break; } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +return ret; +} av_free(url); -return ret; -} -av_free(url); } if (seg && seg->key_type == KEY_SAMPLE_AES) { @@ -2121,7 +2121,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) ret = ff_hls_senc_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); else -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) return ret; -- 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".
[FFmpeg-devel] [PATCH 3/4] libavformat/hls: add support for decryption of HLS media segments encrypted using SAMPLE-AES encryption method
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile| 2 +- libavformat/hls.c | 128 +++-- libavformat/hls_sample_encryption.c | 389 libavformat/hls_sample_encryption.h | 65 + libavformat/mpegts.c| 11 + 5 files changed, 576 insertions(+), 19 deletions(-) create mode 100644 libavformat/hls_sample_encryption.c create mode 100644 libavformat/hls_sample_encryption.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 813ddd3c20..7e3c9c23c6 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -238,7 +238,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_encryption.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 3c1b80f60c..022dae0391 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_encryption.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -214,6 +219,7 @@ typedef struct HLSContext { int http_multiple; int http_seekable; AVIOContext *playlist_pb; +HLSCryptoContext crypto_ctx; } HLSContext; static void free_segment_dynarray(struct segment **segments, int n_segments) @@ -1006,7 +1012,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int64_t n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1035,17 +1044,18 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); for (meta = *extra_meta; meta; meta = meta->next) { if (!strcmp(meta->tag, "PRIV")) { ID3v2ExtraMetaPRIV *priv = &meta->data.priv; -if (priv->datasize == 8 && !strcmp(priv->owner, id3_priv_owner_ts)) { +if (priv->datasize == 8 && !av_strncasecmp(priv->owner, id3_priv_owner_ts, 44)) { /* 33-bit MPEG timestamp */ int64_t ts = AV_RB64(priv->data); av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts); @@ -1053,6 +1063,8 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, *dts = ts; else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); +} else if (priv->datasize >= 8 && !av_strncasecmp(priv->owner, id3_priv_owner_audio_setup, 36)) { +ff_hls_senc_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); } } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; @@ -1096,7 +1108,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE
[FFmpeg-devel] [PATCH 2/4] libavformat/mov: add support for 'cens', 'cbc1' and 'cbcs' encryption schemes specified in Common Encryption (CENC) standard
correct implementation of 'cenc' encryption scheme to support decryption of partial cipher blocks at the end of subsamples https://www.iso.org/standard/68042.html Signed-off-by: Nachiket Tarate --- libavformat/isom.h | 2 + libavformat/mov.c | 246 +++-- 2 files changed, 242 insertions(+), 6 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index ac1b3f3d56..705813844f 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -237,6 +237,8 @@ typedef struct MOVStreamContext { int has_sidx; // If there is an sidx entry for this stream. struct { struct AVAESCTR* aes_ctr; +struct AVAES *aes_ctx; +unsigned int frag_index_entry_base; unsigned int per_sample_iv_size; // Either 0, 8, or 16. AVEncryptionInfo *default_encrypted_sample; MOVEncryptionIndex *encryption_index; diff --git a/libavformat/mov.c b/libavformat/mov.c index 46bc7b5aa3..a0f52bd203 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6578,15 +6578,150 @@ static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } -static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) { int i, ret; +int bytes_of_protected_data; +int partially_encrypted_block_size; +uint8_t *partially_encrypted_block; +uint8_t block[16]; -if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) { -av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n"); -return AVERROR_PATCHWELCOME; +if (!sc->cenc.aes_ctr) { +/* initialize the cipher */ +sc->cenc.aes_ctr = av_aes_ctr_alloc(); +if (!sc->cenc.aes_ctr) { +return AVERROR(ENOMEM); +} + +ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key); +if (ret < 0) { +return ret; +} +} + +av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv); + +if (!sample->subsample_count) { +/* decrypt the whole packet */ +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size); +return 0; +} + +partially_encrypted_block_size = 0; + +for (i = 0; i < sample->subsample_count; i++) { +if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { +av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); +return AVERROR_INVALIDDATA; +} + +/* skip the clear bytes */ +input += sample->subsamples[i].bytes_of_clear_data; +size -= sample->subsamples[i].bytes_of_clear_data; + +/* decrypt the encrypted bytes */ + +if (partially_encrypted_block_size != 0) +{ +memcpy(block, partially_encrypted_block, partially_encrypted_block_size); +memcpy(block+partially_encrypted_block_size, input, 16-partially_encrypted_block_size); +av_aes_ctr_crypt(sc->cenc.aes_ctr, block, block, 16); +memcpy(partially_encrypted_block, block, partially_encrypted_block_size); +memcpy(input, block+partially_encrypted_block_size, 16-partially_encrypted_block_size); +input += 16-partially_encrypted_block_size; +size -= 16-partially_encrypted_block_size; +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data - (16-partially_encrypted_block_size); +} else { +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data; +} + +if (i < sample->subsample_count-1) { +int num_of_encrypted_blocks = bytes_of_protected_data/16; +partially_encrypted_block_size = bytes_of_protected_data%16; +if (partially_encrypted_block_size != 0) +partially_encrypted_block = input + 16*num_of_encrypted_blocks; +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, 16*num_of_encrypted_blocks); +} else { +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data); +} + +input += bytes_of_protected_data; +size -= bytes_of_protected_data; +} + +if (size > 0) { +av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n"); +return AVERROR_INVALIDDATA; +} + +return 0; +} + +static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +{ +int i, ret; +int num_of_encrypted_blocks; +uint8_t iv[16]
[FFmpeg-devel] [PATCH 1/4] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of sample decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 14 ++ libavcodec/adts_parser.c | 32 3 files changed, 47 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..e4454529c4 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..9ecd67fb5b 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,17 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..32489dadf4 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,35 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) { +av_free(*phdr); +return ret; +} + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) { +av_free(*phdr); +return ret; +} + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 1/4] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of sample decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 14 ++ libavcodec/adts_parser.c | 28 3 files changed, 43 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..e4454529c4 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..9ecd67fb5b 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,17 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..7df714e227 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 2/4] libavformat/mov: add support for 'cens', 'cbc1' and 'cbcs' encryption schemes specified in Common Encryption (CENC) standard
correct implementation of 'cenc' encryption scheme to support decryption of partial cipher blocks at the end of subsamples https://www.iso.org/standard/68042.html Signed-off-by: Nachiket Tarate --- libavformat/isom.h | 2 + libavformat/mov.c | 246 +++-- 2 files changed, 242 insertions(+), 6 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index ac1b3f3d56..705813844f 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -237,6 +237,8 @@ typedef struct MOVStreamContext { int has_sidx; // If there is an sidx entry for this stream. struct { struct AVAESCTR* aes_ctr; +struct AVAES *aes_ctx; +unsigned int frag_index_entry_base; unsigned int per_sample_iv_size; // Either 0, 8, or 16. AVEncryptionInfo *default_encrypted_sample; MOVEncryptionIndex *encryption_index; diff --git a/libavformat/mov.c b/libavformat/mov.c index e95d3d2a90..4c55741293 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6578,15 +6578,150 @@ static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } -static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) { int i, ret; +int bytes_of_protected_data; +int partially_encrypted_block_size; +uint8_t *partially_encrypted_block; +uint8_t block[16]; -if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) { -av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n"); -return AVERROR_PATCHWELCOME; +if (!sc->cenc.aes_ctr) { +/* initialize the cipher */ +sc->cenc.aes_ctr = av_aes_ctr_alloc(); +if (!sc->cenc.aes_ctr) { +return AVERROR(ENOMEM); +} + +ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key); +if (ret < 0) { +return ret; +} +} + +av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv); + +if (!sample->subsample_count) { +/* decrypt the whole packet */ +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size); +return 0; +} + +partially_encrypted_block_size = 0; + +for (i = 0; i < sample->subsample_count; i++) { +if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { +av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); +return AVERROR_INVALIDDATA; +} + +/* skip the clear bytes */ +input += sample->subsamples[i].bytes_of_clear_data; +size -= sample->subsamples[i].bytes_of_clear_data; + +/* decrypt the encrypted bytes */ + +if (partially_encrypted_block_size != 0) +{ +memcpy(block, partially_encrypted_block, partially_encrypted_block_size); +memcpy(block+partially_encrypted_block_size, input, 16-partially_encrypted_block_size); +av_aes_ctr_crypt(sc->cenc.aes_ctr, block, block, 16); +memcpy(partially_encrypted_block, block, partially_encrypted_block_size); +memcpy(input, block+partially_encrypted_block_size, 16-partially_encrypted_block_size); +input += 16-partially_encrypted_block_size; +size -= 16-partially_encrypted_block_size; +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data - (16-partially_encrypted_block_size); +} else { +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data; +} + +if (i < sample->subsample_count-1) { +int num_of_encrypted_blocks = bytes_of_protected_data/16; +partially_encrypted_block_size = bytes_of_protected_data%16; +if (partially_encrypted_block_size != 0) +partially_encrypted_block = input + 16*num_of_encrypted_blocks; +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, 16*num_of_encrypted_blocks); +} else { +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data); +} + +input += bytes_of_protected_data; +size -= bytes_of_protected_data; +} + +if (size > 0) { +av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n"); +return AVERROR_INVALIDDATA; +} + +return 0; +} + +static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +{ +int i, ret; +int num_of_encrypted_blocks; +uint8_t iv[16]
[FFmpeg-devel] [PATCH 4/4] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 022dae0391..7e457281f4 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2051,23 +2051,23 @@ static int hls_read_header(AVFormatContext *s) if (in_fmt->raw_codec_id == pls->audio_setup_info.codec_id) break; } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +return ret; +} av_free(url); -return ret; -} -av_free(url); } if (seg && seg->key_type == KEY_SAMPLE_AES) { @@ -2121,7 +2121,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) ret = ff_hls_senc_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); else -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) return ret; -- 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".
[FFmpeg-devel] [PATCH 3/4] libavformat/hls: add support for decryption of HLS media segments encrypted using SAMPLE-AES encryption method
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile| 2 +- libavformat/hls.c | 128 +++-- libavformat/hls_sample_encryption.c | 389 libavformat/hls_sample_encryption.h | 65 + libavformat/mpegts.c| 11 + 5 files changed, 576 insertions(+), 19 deletions(-) create mode 100644 libavformat/hls_sample_encryption.c create mode 100644 libavformat/hls_sample_encryption.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 813ddd3c20..7e3c9c23c6 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -238,7 +238,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_encryption.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 3c1b80f60c..022dae0391 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_encryption.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -214,6 +219,7 @@ typedef struct HLSContext { int http_multiple; int http_seekable; AVIOContext *playlist_pb; +HLSCryptoContext crypto_ctx; } HLSContext; static void free_segment_dynarray(struct segment **segments, int n_segments) @@ -1006,7 +1012,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int64_t n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1035,17 +1044,18 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); for (meta = *extra_meta; meta; meta = meta->next) { if (!strcmp(meta->tag, "PRIV")) { ID3v2ExtraMetaPRIV *priv = &meta->data.priv; -if (priv->datasize == 8 && !strcmp(priv->owner, id3_priv_owner_ts)) { +if (priv->datasize == 8 && !av_strncasecmp(priv->owner, id3_priv_owner_ts, 44)) { /* 33-bit MPEG timestamp */ int64_t ts = AV_RB64(priv->data); av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts); @@ -1053,6 +1063,8 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, *dts = ts; else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); +} else if (priv->datasize >= 8 && !av_strncasecmp(priv->owner, id3_priv_owner_audio_setup, 36)) { +ff_hls_senc_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); } } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; @@ -1096,7 +1108,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE
[FFmpeg-devel] [PATCH 2/4] libavformat/mov: add support for 'cens', 'cbc1' and 'cbcs' encryption schemes specified in Common Encryption (CENC) standard
correct implementation of 'cenc' encryption scheme to support decryption of partial cipher blocks at the end of subsamples https://www.iso.org/standard/68042.html Signed-off-by: Nachiket Tarate --- libavformat/isom.h | 2 + libavformat/mov.c | 246 +++-- 2 files changed, 242 insertions(+), 6 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index ac1b3f3d56..705813844f 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -237,6 +237,8 @@ typedef struct MOVStreamContext { int has_sidx; // If there is an sidx entry for this stream. struct { struct AVAESCTR* aes_ctr; +struct AVAES *aes_ctx; +unsigned int frag_index_entry_base; unsigned int per_sample_iv_size; // Either 0, 8, or 16. AVEncryptionInfo *default_encrypted_sample; MOVEncryptionIndex *encryption_index; diff --git a/libavformat/mov.c b/libavformat/mov.c index a37a9cc917..0da1bc606f 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6577,15 +6577,150 @@ static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } -static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) { int i, ret; +int bytes_of_protected_data; +int partially_encrypted_block_size; +uint8_t *partially_encrypted_block; +uint8_t block[16]; -if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) { -av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n"); -return AVERROR_PATCHWELCOME; +if (!sc->cenc.aes_ctr) { +/* initialize the cipher */ +sc->cenc.aes_ctr = av_aes_ctr_alloc(); +if (!sc->cenc.aes_ctr) { +return AVERROR(ENOMEM); +} + +ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key); +if (ret < 0) { +return ret; +} +} + +av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv); + +if (!sample->subsample_count) { +/* decrypt the whole packet */ +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size); +return 0; +} + +partially_encrypted_block_size = 0; + +for (i = 0; i < sample->subsample_count; i++) { +if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { +av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); +return AVERROR_INVALIDDATA; +} + +/* skip the clear bytes */ +input += sample->subsamples[i].bytes_of_clear_data; +size -= sample->subsamples[i].bytes_of_clear_data; + +/* decrypt the encrypted bytes */ + +if (partially_encrypted_block_size != 0) +{ +memcpy(block, partially_encrypted_block, partially_encrypted_block_size); +memcpy(block+partially_encrypted_block_size, input, 16-partially_encrypted_block_size); +av_aes_ctr_crypt(sc->cenc.aes_ctr, block, block, 16); +memcpy(partially_encrypted_block, block, partially_encrypted_block_size); +memcpy(input, block+partially_encrypted_block_size, 16-partially_encrypted_block_size); +input += 16-partially_encrypted_block_size; +size -= 16-partially_encrypted_block_size; +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data - (16-partially_encrypted_block_size); +} else { +bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data; +} + +if (i < sample->subsample_count-1) { +int num_of_encrypted_blocks = bytes_of_protected_data/16; +partially_encrypted_block_size = bytes_of_protected_data%16; +if (partially_encrypted_block_size != 0) +partially_encrypted_block = input + 16*num_of_encrypted_blocks; +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, 16*num_of_encrypted_blocks); +} else { +av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data); +} + +input += bytes_of_protected_data; +size -= bytes_of_protected_data; +} + +if (size > 0) { +av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n"); +return AVERROR_INVALIDDATA; +} + +return 0; +} + +static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +{ +int i, ret; +int num_of_encrypted_blocks; +uint8_t iv[16]
[FFmpeg-devel] [PATCH 4/4] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 022dae0391..7e457281f4 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2051,23 +2051,23 @@ static int hls_read_header(AVFormatContext *s) if (in_fmt->raw_codec_id == pls->audio_setup_info.codec_id) break; } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +return ret; +} av_free(url); -return ret; -} -av_free(url); } if (seg && seg->key_type == KEY_SAMPLE_AES) { @@ -2121,7 +2121,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) ret = ff_hls_senc_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); else -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) return ret; -- 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".
[FFmpeg-devel] [PATCH 1/4] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of sample decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 14 ++ libavcodec/adts_parser.c | 28 3 files changed, 43 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..e4454529c4 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..9ecd67fb5b 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,17 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..7df714e227 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 3/4] libavformat/hls: add support for decryption of HLS media segments encrypted using SAMPLE-AES encryption method
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile| 2 +- libavformat/hls.c | 128 +++-- libavformat/hls_sample_encryption.c | 389 libavformat/hls_sample_encryption.h | 65 + libavformat/mpegts.c| 11 + 5 files changed, 576 insertions(+), 19 deletions(-) create mode 100644 libavformat/hls_sample_encryption.c create mode 100644 libavformat/hls_sample_encryption.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 813ddd3c20..7e3c9c23c6 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -238,7 +238,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_encryption.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 3c1b80f60c..022dae0391 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_encryption.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -214,6 +219,7 @@ typedef struct HLSContext { int http_multiple; int http_seekable; AVIOContext *playlist_pb; +HLSCryptoContext crypto_ctx; } HLSContext; static void free_segment_dynarray(struct segment **segments, int n_segments) @@ -1006,7 +1012,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int64_t n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1035,17 +1044,18 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); for (meta = *extra_meta; meta; meta = meta->next) { if (!strcmp(meta->tag, "PRIV")) { ID3v2ExtraMetaPRIV *priv = &meta->data.priv; -if (priv->datasize == 8 && !strcmp(priv->owner, id3_priv_owner_ts)) { +if (priv->datasize == 8 && !av_strncasecmp(priv->owner, id3_priv_owner_ts, 44)) { /* 33-bit MPEG timestamp */ int64_t ts = AV_RB64(priv->data); av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts); @@ -1053,6 +1063,8 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, *dts = ts; else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); +} else if (priv->datasize >= 8 && !av_strncasecmp(priv->owner, id3_priv_owner_audio_setup, 36)) { +ff_hls_senc_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); } } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; @@ -1096,7 +1108,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE
[FFmpeg-devel] [PATCH 4/4] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 51b8da7c99..3c9a5bca90 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2051,23 +2051,23 @@ static int hls_read_header(AVFormatContext *s) if (in_fmt->raw_codec_id == pls->audio_setup_info.codec_id) break; } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +goto fail; +} av_free(url); -goto fail; -} -av_free(url); } if (seg && seg->key_type == KEY_SAMPLE_AES) { @@ -2119,7 +2119,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) ret = ff_hls_senc_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); else -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) goto fail; -- 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".
[FFmpeg-devel] [PATCH 3/4] libavformat/hls: add support for decryption of HLS media segments encrypted using SAMPLE-AES encryption method
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile| 2 +- libavformat/hls.c | 123 - libavformat/hls_sample_encryption.c | 391 libavformat/hls_sample_encryption.h | 65 + libavformat/mpegts.c| 12 + 5 files changed, 578 insertions(+), 15 deletions(-) create mode 100644 libavformat/hls_sample_encryption.c create mode 100644 libavformat/hls_sample_encryption.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 0f340f74a0..56fdc65e1a 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -236,7 +236,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_encryption.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 597bea7f25..51b8da7c99 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_encryption.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -213,6 +218,7 @@ typedef struct HLSContext { int http_multiple; int http_seekable; AVIOContext *playlist_pb; +HLSCryptoContext crypto_ctx; } HLSContext; static void free_segment_dynarray(struct segment **segments, int n_segments) @@ -1001,7 +1007,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int64_t n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1030,10 +1039,11 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); @@ -1048,6 +1058,8 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, *dts = ts; else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); +} else if (priv->datasize >= 8 && !strcmp(priv->owner, id3_priv_owner_audio_setup)) { +ff_hls_senc_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); } } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; @@ -1091,7 +1103,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE; -parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta); +parse_id3(pls->ctx, pb, &metadata, ×tamp, &pls->audio_setup_info, &apic, &extra_meta); if (timestamp != AV_NOPTS_VALUE) { pls->id3_mpegts_timestamp = timestamp; @@ -1245,10 +1257,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n", seg->url, seg->url_offset, pls->index); -
[FFmpeg-devel] [PATCH 2/4] libavformat/mov: add support for 'cbcs' encryption scheme specified in Common Encryption (CENC) standard
https://www.iso.org/standard/68042.html Signed-off-by: Nachiket Tarate --- libavformat/isom.h | 1 + libavformat/mov.c | 86 ++ 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 5a6d504090..5a17cb9c07 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -237,6 +237,7 @@ typedef struct MOVStreamContext { int has_sidx; // If there is an sidx entry for this stream. struct { struct AVAESCTR* aes_ctr; +struct AVAES*aes_ctx; unsigned int per_sample_iv_size; // Either 0, 8, or 16. AVEncryptionInfo *default_encrypted_sample; MOVEncryptionIndex *encryption_index; diff --git a/libavformat/mov.c b/libavformat/mov.c index 43c55ef4a4..5eda5f3822 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6623,15 +6623,10 @@ static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } -static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) { int i, ret; -if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) { -av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n"); -return AVERROR_PATCHWELCOME; -} - if (!sc->cenc.aes_ctr) { /* initialize the cipher */ sc->cenc.aes_ctr = av_aes_ctr_alloc(); @@ -6654,6 +6649,7 @@ static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *s } for (i = 0; i < sample->subsample_count; i++) { + if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); return AVERROR_INVALIDDATA; @@ -6677,6 +6673,84 @@ static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *s return 0; } +static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size) +{ +int i, ret; +int encrypted_blocks; +uint8_t iv[16]; + +if (!sc->cenc.aes_ctx) { +/* initialize the cipher */ +sc->cenc.aes_ctx = av_aes_alloc(); +if (!sc->cenc.aes_ctx) { +return AVERROR(ENOMEM); +} + +ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1); +if (ret < 0) { +return ret; +} +} + +/* whole-block full sample encryption */ +if (!sample->subsample_count) { +/* decrypt the whole packet */ +memcpy(iv, sample->iv, 16); +av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1); +return 0; +} + +for (i = 0; i < sample->subsample_count; i++) { + +if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { +av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); +return AVERROR_INVALIDDATA; +} + +/* skip the clear bytes */ +input += sample->subsamples[i].bytes_of_clear_data; +size -= sample->subsamples[i].bytes_of_clear_data; + +/* decrypt the encrypted bytes */ +memcpy(iv, sample->iv, 16); +encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16; +if (encrypted_blocks > 0) { +/* pattern encryption */ +if (sample->crypt_byte_block > 0 && sample->skip_byte_block > 0) { +uint8_t *data = input; +int rem_bytes = sample->subsamples[i].bytes_of_protected_data; +while (rem_bytes > 0) { +if (rem_bytes > 16*sample->crypt_byte_block) { +av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1); +data += 16*sample->crypt_byte_block; +rem_bytes -= 16*sample->crypt_byte_block; +} +data += FFMIN(16*sample->skip_byte_block, rem_bytes); +rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes); +} +} else { +av_aes_crypt(sc->cenc.aes_ctx, input, input, encrypted_blocks, iv, 1); +} +} +input += sample->subsamples[i].bytes_of_protected_data; +size -= sample->subsamples[i].bytes_of_protected_data; +} + +return 0; +} + +static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEn
[FFmpeg-devel] [PATCH 1/4] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of sample decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 14 ++ libavcodec/adts_parser.c | 28 3 files changed, 43 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..e4454529c4 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..9ecd67fb5b 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,17 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..7df714e227 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
Re: [FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for decryption of HLS streams in MPEG-TS format protected using SAMPLE-AES encryption
On Wed, Mar 3, 2021 at 11:15 AM Nachiket Tarate wrote: > > On Mon, Mar 1, 2021 at 1:05 PM Steven Liu wrote: > > > > > > > > > 2021年3月1日 下午3:22,Nachiket Tarate 写道: > > > > > > On Mon, Mar 1, 2021 at 11:30 AM Steven Liu wrote: > > >> > > >> > > >> > > >>> 2021年3月1日 下午12:55,Nachiket Tarate 写道: > > >>> > > >>> This is an updated version of the patch in which I have added the > > >>> check. If > > >>> the segments are in Fragmented MP4 format, HLS demuxer quits by giving > > >>> an > > >>> error message: > > >>> > > >>> "SAMPLE-AES encryption is not supported for fragmented MP4 format yet” > > >> I don’t think is a good resolution for SAMPLE-AES encryption and > > >> decryption. > > >> You should support that if you want support SAMPLE-AES in hls, > > >> because SAMPLE-AES not only support in MPEG-TS, but also support > > >> fragment mp4. > > >> Whatever, if you only support mpegts en[de]cryption, it should be a half > > >> part patch. > > > > > > Two completely different technologies/specifications have been used > > > for SAMPLE-AES encryption of HLS streams in MPEG-TS and fragmented MP4 > > > formats. > > > > > > Fragmented MP4 media segments are encrypted using the 'cbcs' scheme of > > > Common Encryption [CENC]: > > > > > > https://www.iso.org/standard/68042.html > > > > > > Encryption of other media segment formats such as MPEG-TS or external > > > audio tracks containing H.264, AAC, AC-3 and Enhanced AC-3 media > > > streams is described in the Apple's HTTP Live Streaming (HLS) Sample > > > Encryption specifications: > > > > > > https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption > > > > > > This patch implements the later specifications and enables decryption > > > of media segments in MPEG-TS, AAC, AC-3 and Enhanced AC-3 formats. So > > > I think we should merge this patch right now. > > > > I think sample ads should support not only mpegts, but also support fmp4 > > too. > > Reference rfc8216 context: > > An encryption method of SAMPLE-AES means that the Media Segments > > contain media samples, such as audio or video, that are encrypted > > using the Advanced Encryption Standard [AES_128]. How these media > > streams are encrypted and encapsulated in a segment depends on the > > media encoding and the media format of the segment. fMP4 Media > > Segments are encrypted using the 'cbcs' scheme of Common > > Encryption [COMMON_ENC]. Encryption of other Media Segment > > formats containing H.264 [H_264], AAC [ISO_14496], AC-3 [AC_3], > > and Enhanced AC-3 [AC_3] media streams is described in the HTTP > > Live Streaming (HLS) Sample Encryption specification [SampleEnc]. > > The IV attribute MAY be present; see Section 5.2. > > > > And I saw the m3u8 context, the METHOD is SAMPLE-AES. > > > > (base) liuqi05:ufbuild liuqi$ head -n10 prog_index.m3u8 > > #EXTM3U > > #EXT-X-TARGETDURATION:10 > > #EXT-X-VERSION:7 > > #EXT-X-MEDIA-SEQUENCE:0 > > #EXT-X-PLAYLIST-TYPE:VOD > > #EXT-X-INDEPENDENT-SEGMENTS > > > > Focus on this line. > > #EXT-X-KEY:METHOD=SAMPLE-AES,URI="http://127.0.0.1/keyOnly.bin",IV=0xcece273e2737a58ca785e257eb080482 > > > > > > #EXT-X-MAP:URI="fileSequence0.mp4" > > #EXTINF:8.31667, > > #EXT-X-BITRATE:7064 > > > > > > You can point me the part if I misunderstood SAMPLE-AES. > > Your understanding of SAMPLE-AES is absolutely correct. > > I am insisting that let us add support for it in 2 phases as > completely 2 different specifications have been used. > > Phase 1 : Media segments in MPEG-TS, AAC, AC-3 and Enhanced AC-3 > formats (Apple's specifications) > > Phase 2 : Media segments in fragmented MP4 format (CENC specifications) > > Kindly let me know your opinion. Hello Steven, I am looking forward to hearing from you. Best Regards, Nachiket > > > > > > > In future, we will add support for CENC or see how can we use existing > > > things from MOV demuxer. > > > > > > Best Regards, > > > Nachiket Tarate > > > > > >>> > > >>> Best Regards, > > >>> Nachiket Tarate > > >>> >
Re: [FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for decryption of HLS streams in MPEG-TS format protected using SAMPLE-AES encryption
On Mon, Mar 1, 2021 at 1:05 PM Steven Liu wrote: > > > > > 2021年3月1日 下午3:22,Nachiket Tarate 写道: > > > > On Mon, Mar 1, 2021 at 11:30 AM Steven Liu wrote: > >> > >> > >> > >>> 2021年3月1日 下午12:55,Nachiket Tarate 写道: > >>> > >>> This is an updated version of the patch in which I have added the check. > >>> If > >>> the segments are in Fragmented MP4 format, HLS demuxer quits by giving an > >>> error message: > >>> > >>> "SAMPLE-AES encryption is not supported for fragmented MP4 format yet” > >> I don’t think is a good resolution for SAMPLE-AES encryption and > >> decryption. > >> You should support that if you want support SAMPLE-AES in hls, > >> because SAMPLE-AES not only support in MPEG-TS, but also support fragment > >> mp4. > >> Whatever, if you only support mpegts en[de]cryption, it should be a half > >> part patch. > > > > Two completely different technologies/specifications have been used > > for SAMPLE-AES encryption of HLS streams in MPEG-TS and fragmented MP4 > > formats. > > > > Fragmented MP4 media segments are encrypted using the 'cbcs' scheme of > > Common Encryption [CENC]: > > > > https://www.iso.org/standard/68042.html > > > > Encryption of other media segment formats such as MPEG-TS or external > > audio tracks containing H.264, AAC, AC-3 and Enhanced AC-3 media > > streams is described in the Apple's HTTP Live Streaming (HLS) Sample > > Encryption specifications: > > > > https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption > > > > This patch implements the later specifications and enables decryption > > of media segments in MPEG-TS, AAC, AC-3 and Enhanced AC-3 formats. So > > I think we should merge this patch right now. > > I think sample ads should support not only mpegts, but also support fmp4 too. > Reference rfc8216 context: > An encryption method of SAMPLE-AES means that the Media Segments > contain media samples, such as audio or video, that are encrypted > using the Advanced Encryption Standard [AES_128]. How these media > streams are encrypted and encapsulated in a segment depends on the > media encoding and the media format of the segment. fMP4 Media > Segments are encrypted using the 'cbcs' scheme of Common > Encryption [COMMON_ENC]. Encryption of other Media Segment > formats containing H.264 [H_264], AAC [ISO_14496], AC-3 [AC_3], > and Enhanced AC-3 [AC_3] media streams is described in the HTTP > Live Streaming (HLS) Sample Encryption specification [SampleEnc]. > The IV attribute MAY be present; see Section 5.2. > > And I saw the m3u8 context, the METHOD is SAMPLE-AES. > > (base) liuqi05:ufbuild liuqi$ head -n10 prog_index.m3u8 > #EXTM3U > #EXT-X-TARGETDURATION:10 > #EXT-X-VERSION:7 > #EXT-X-MEDIA-SEQUENCE:0 > #EXT-X-PLAYLIST-TYPE:VOD > #EXT-X-INDEPENDENT-SEGMENTS > > Focus on this line. > #EXT-X-KEY:METHOD=SAMPLE-AES,URI="http://127.0.0.1/keyOnly.bin",IV=0xcece273e2737a58ca785e257eb080482 > > > #EXT-X-MAP:URI="fileSequence0.mp4" > #EXTINF:8.31667, > #EXT-X-BITRATE:7064 > > > You can point me the part if I misunderstood SAMPLE-AES. Your understanding of SAMPLE-AES is absolutely correct. I am insisting that let us add support for it in 2 phases as completely 2 different specifications have been used. Phase 1 : Media segments in MPEG-TS, AAC, AC-3 and Enhanced AC-3 formats (Apple's specifications) Phase 2 : Media segments in fragmented MP4 format (CENC specifications) Kindly let me know your opinion. > > > > In future, we will add support for CENC or see how can we use existing > > things from MOV demuxer. > > > > Best Regards, > > Nachiket Tarate > > > >>> > >>> Best Regards, > >>> Nachiket Tarate > >>> > >>> On Mon, Mar 1, 2021 at 10:13 AM Steven Liu wrote: > >>> > >>>> > >>>> > >>>>> 2021年3月1日 下午12:35,Nachiket Tarate 写道: > >>>>> > >>>>> @Steven Liu > >>>>> > >>>>> Can we merge this patch ? > >>>> I’m waiting update patch for fragment mp4 encryption. > >>>> After new version of the patchset I will test and review. > >>>>> > >>>>> Best Regards, > >>>>> Nachiket Tarate > >>>>> > >>>>> On Wed, Feb 24, 2021 at 4:44 PM Nac
Re: [FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for decryption of HLS streams in MPEG-TS format protected using SAMPLE-AES encryption
On Mon, Mar 1, 2021 at 11:30 AM Steven Liu wrote: > > > > > 2021年3月1日 下午12:55,Nachiket Tarate 写道: > > > > This is an updated version of the patch in which I have added the check. If > > the segments are in Fragmented MP4 format, HLS demuxer quits by giving an > > error message: > > > > "SAMPLE-AES encryption is not supported for fragmented MP4 format yet” > I don’t think is a good resolution for SAMPLE-AES encryption and decryption. > You should support that if you want support SAMPLE-AES in hls, > because SAMPLE-AES not only support in MPEG-TS, but also support fragment mp4. > Whatever, if you only support mpegts en[de]cryption, it should be a half part > patch. Two completely different technologies/specifications have been used for SAMPLE-AES encryption of HLS streams in MPEG-TS and fragmented MP4 formats. Fragmented MP4 media segments are encrypted using the 'cbcs' scheme of Common Encryption [CENC]: https://www.iso.org/standard/68042.html Encryption of other media segment formats such as MPEG-TS or external audio tracks containing H.264, AAC, AC-3 and Enhanced AC-3 media streams is described in the Apple's HTTP Live Streaming (HLS) Sample Encryption specifications: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption This patch implements the later specifications and enables decryption of media segments in MPEG-TS, AAC, AC-3 and Enhanced AC-3 formats. So I think we should merge this patch right now. In future, we will add support for CENC or see how can we use existing things from MOV demuxer. Best Regards, Nachiket Tarate > > > > Best Regards, > > Nachiket Tarate > > > > On Mon, Mar 1, 2021 at 10:13 AM Steven Liu wrote: > > > >> > >> > >>> 2021年3月1日 下午12:35,Nachiket Tarate 写道: > >>> > >>> @Steven Liu > >>> > >>> Can we merge this patch ? > >> I’m waiting update patch for fragment mp4 encryption. > >> After new version of the patchset I will test and review. > >>> > >>> Best Regards, > >>> Nachiket Tarate > >>> > >>> On Wed, Feb 24, 2021 at 4:44 PM Nachiket Tarate < > >>> nachiket.program...@gmail.com> wrote: > >>> > >>>> Apple HTTP Live Streaming Sample Encryption: > >>>> > >>>> > >>>> > >> https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption > >>>> > >>>> Signed-off-by: Nachiket Tarate > >>>> --- > >>>> libavformat/Makefile | 2 +- > >>>> libavformat/hls.c| 105 -- > >>>> libavformat/hls_sample_aes.c | 391 +++ > >>>> libavformat/hls_sample_aes.h | 66 ++ > >>>> libavformat/mpegts.c | 12 ++ > >>>> 5 files changed, 562 insertions(+), 14 deletions(-) > >>>> create mode 100644 libavformat/hls_sample_aes.c > >>>> create mode 100644 libavformat/hls_sample_aes.h > >>>> > >>>> diff --git a/libavformat/Makefile b/libavformat/Makefile > >>>> index fcb39ce133..62627d50a6 100644 > >>>> --- a/libavformat/Makefile > >>>> +++ b/libavformat/Makefile > >>>> @@ -236,7 +236,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o > >>>> pcm.o > >>>> OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o > >>>> OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o > >>>> OBJS-$(CONFIG_HEVC_MUXER) += rawenc.o > >>>> -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o > >>>> +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o > >>>> OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o > >>>> OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o > >>>> OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o > >>>> diff --git a/libavformat/hls.c b/libavformat/hls.c > >>>> index af2468ad9b..3cb3853c79 100644 > >>>> --- a/libavformat/hls.c > >>>> +++ b/libavformat/hls.c > >>>> @@ -2,6 +2,7 @@ > >>>> * Apple HTTP Live Streaming demuxer > >>>> * Copyright (c) 2010 Martin Storsjo > >>>> * Copyright (c) 2013 Anssi Hannula > >>>> + * Copyright (c) 2021 Nachiket Tarate > >>>> * > >>>> * This file is part of FFmpeg. > >>>> * > >>>> @@ -39,6 +40,8 @@
Re: [FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for decryption of HLS streams in MPEG-TS format protected using SAMPLE-AES encryption
This is an updated version of the patch in which I have added the check. If the segments are in Fragmented MP4 format, HLS demuxer quits by giving an error message: "SAMPLE-AES encryption is not supported for fragmented MP4 format yet" Best Regards, Nachiket Tarate On Mon, Mar 1, 2021 at 10:13 AM Steven Liu wrote: > > > > 2021年3月1日 下午12:35,Nachiket Tarate 写道: > > > > @Steven Liu > > > > Can we merge this patch ? > I’m waiting update patch for fragment mp4 encryption. > After new version of the patchset I will test and review. > > > > Best Regards, > > Nachiket Tarate > > > > On Wed, Feb 24, 2021 at 4:44 PM Nachiket Tarate < > > nachiket.program...@gmail.com> wrote: > > > >> Apple HTTP Live Streaming Sample Encryption: > >> > >> > >> > https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption > >> > >> Signed-off-by: Nachiket Tarate > >> --- > >> libavformat/Makefile | 2 +- > >> libavformat/hls.c| 105 -- > >> libavformat/hls_sample_aes.c | 391 +++ > >> libavformat/hls_sample_aes.h | 66 ++ > >> libavformat/mpegts.c | 12 ++ > >> 5 files changed, 562 insertions(+), 14 deletions(-) > >> create mode 100644 libavformat/hls_sample_aes.c > >> create mode 100644 libavformat/hls_sample_aes.h > >> > >> diff --git a/libavformat/Makefile b/libavformat/Makefile > >> index fcb39ce133..62627d50a6 100644 > >> --- a/libavformat/Makefile > >> +++ b/libavformat/Makefile > >> @@ -236,7 +236,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o > >> pcm.o > >> OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o > >> OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o > >> OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o > >> -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o > >> +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o > >> OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o > >> OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o > >> OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o > >> diff --git a/libavformat/hls.c b/libavformat/hls.c > >> index af2468ad9b..3cb3853c79 100644 > >> --- a/libavformat/hls.c > >> +++ b/libavformat/hls.c > >> @@ -2,6 +2,7 @@ > >> * Apple HTTP Live Streaming demuxer > >> * Copyright (c) 2010 Martin Storsjo > >> * Copyright (c) 2013 Anssi Hannula > >> + * Copyright (c) 2021 Nachiket Tarate > >> * > >> * This file is part of FFmpeg. > >> * > >> @@ -39,6 +40,8 @@ > >> #include "avio_internal.h" > >> #include "id3v2.h" > >> > >> +#include "hls_sample_aes.h" > >> + > >> #define INITIAL_BUFFER_SIZE 32768 > >> > >> #define MAX_FIELD_LEN 64 > >> @@ -145,6 +148,10 @@ struct playlist { > >> int id3_changed; /* ID3 tag data has changed at some point */ > >> ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer > >> is opened */ > >> > >> +/* Used in case of SAMPLE-AES encryption method */ > >> +HLSAudioSetupInfo audio_setup_info; > >> +HLSCryptoContext crypto_ctx; > >> + > >> int64_t seek_timestamp; > >> int seek_flags; > >> int seek_stream_index; /* into subdemuxer stream array */ > >> @@ -266,6 +273,8 @@ static void free_playlist_list(HLSContext *c) > >> pls->ctx->pb = NULL; > >> avformat_close_input(&pls->ctx); > >> } > >> +if (pls->crypto_ctx.aes_ctx) > >> + av_free(pls->crypto_ctx.aes_ctx); > >> av_free(pls); > >> } > >> av_freep(&c->playlists); > >> @@ -994,7 +1003,10 @@ fail: > >> > >> static struct segment *current_segment(struct playlist *pls) > >> { > >> -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; > >> +int64_t n = pls->cur_seq_no - pls->start_seq_no; > >> +if (n >= pls->n_segments) > >> +return NULL; > >> +return pls->segments[n]; > >> } > >> > >> static struct segment *next_segment(struct playlist *pls) > >> @@ -1023,10 +1035,11 @@ static int read_from_url(struct playlist *pls, > >> struct segment *seg, &g
Re: [FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for decryption of HLS streams in MPEG-TS format protected using SAMPLE-AES encryption
@Steven Liu Can we merge this patch ? Best Regards, Nachiket Tarate On Wed, Feb 24, 2021 at 4:44 PM Nachiket Tarate < nachiket.program...@gmail.com> wrote: > Apple HTTP Live Streaming Sample Encryption: > > > https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption > > Signed-off-by: Nachiket Tarate > --- > libavformat/Makefile | 2 +- > libavformat/hls.c| 105 -- > libavformat/hls_sample_aes.c | 391 +++ > libavformat/hls_sample_aes.h | 66 ++ > libavformat/mpegts.c | 12 ++ > 5 files changed, 562 insertions(+), 14 deletions(-) > create mode 100644 libavformat/hls_sample_aes.c > create mode 100644 libavformat/hls_sample_aes.h > > diff --git a/libavformat/Makefile b/libavformat/Makefile > index fcb39ce133..62627d50a6 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -236,7 +236,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o > pcm.o > OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o > OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o > OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o > -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o > +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o > OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o > OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o > OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o > diff --git a/libavformat/hls.c b/libavformat/hls.c > index af2468ad9b..3cb3853c79 100644 > --- a/libavformat/hls.c > +++ b/libavformat/hls.c > @@ -2,6 +2,7 @@ > * Apple HTTP Live Streaming demuxer > * Copyright (c) 2010 Martin Storsjo > * Copyright (c) 2013 Anssi Hannula > + * Copyright (c) 2021 Nachiket Tarate > * > * This file is part of FFmpeg. > * > @@ -39,6 +40,8 @@ > #include "avio_internal.h" > #include "id3v2.h" > > +#include "hls_sample_aes.h" > + > #define INITIAL_BUFFER_SIZE 32768 > > #define MAX_FIELD_LEN 64 > @@ -145,6 +148,10 @@ struct playlist { > int id3_changed; /* ID3 tag data has changed at some point */ > ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer > is opened */ > > +/* Used in case of SAMPLE-AES encryption method */ > +HLSAudioSetupInfo audio_setup_info; > +HLSCryptoContext crypto_ctx; > + > int64_t seek_timestamp; > int seek_flags; > int seek_stream_index; /* into subdemuxer stream array */ > @@ -266,6 +273,8 @@ static void free_playlist_list(HLSContext *c) > pls->ctx->pb = NULL; > avformat_close_input(&pls->ctx); > } > +if (pls->crypto_ctx.aes_ctx) > + av_free(pls->crypto_ctx.aes_ctx); > av_free(pls); > } > av_freep(&c->playlists); > @@ -994,7 +1003,10 @@ fail: > > static struct segment *current_segment(struct playlist *pls) > { > -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; > +int64_t n = pls->cur_seq_no - pls->start_seq_no; > +if (n >= pls->n_segments) > +return NULL; > +return pls->segments[n]; > } > > static struct segment *next_segment(struct playlist *pls) > @@ -1023,10 +1035,11 @@ static int read_from_url(struct playlist *pls, > struct segment *seg, > > /* Parse the raw ID3 data and pass contents to caller */ > static void parse_id3(AVFormatContext *s, AVIOContext *pb, > - AVDictionary **metadata, int64_t *dts, > + AVDictionary **metadata, int64_t *dts, > HLSAudioSetupInfo *audio_setup_info, >ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta > **extra_meta) > { > static const char id3_priv_owner_ts[] = > "com.apple.streaming.transportStreamTimestamp"; > +static const char id3_priv_owner_audio_setup[] = > "com.apple.streaming.audioDescription"; > ID3v2ExtraMeta *meta; > > ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); > @@ -1041,6 +1054,8 @@ static void parse_id3(AVFormatContext *s, > AVIOContext *pb, > *dts = ts; > else > av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio > timestamp %"PRId64"\n", ts); > +} else if (priv->datasize >= 8 && !strcmp(priv->owner, > id3_priv_owner_audio_setup)) { > +ff_hls_read_audio_setup_info(audio_setup_info, > priv->data, priv->datasize); > } > } else if (!strcmp(meta->tag, "APIC") && apic)
[FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for decryption of HLS streams in MPEG-TS format protected using SAMPLE-AES encryption
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile | 2 +- libavformat/hls.c| 105 -- libavformat/hls_sample_aes.c | 391 +++ libavformat/hls_sample_aes.h | 66 ++ libavformat/mpegts.c | 12 ++ 5 files changed, 562 insertions(+), 14 deletions(-) create mode 100644 libavformat/hls_sample_aes.c create mode 100644 libavformat/hls_sample_aes.h diff --git a/libavformat/Makefile b/libavformat/Makefile index fcb39ce133..62627d50a6 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -236,7 +236,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index af2468ad9b..3cb3853c79 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_aes.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,10 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +/* Used in case of SAMPLE-AES encryption method */ +HLSAudioSetupInfo audio_setup_info; +HLSCryptoContext crypto_ctx; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -266,6 +273,8 @@ static void free_playlist_list(HLSContext *c) pls->ctx->pb = NULL; avformat_close_input(&pls->ctx); } +if (pls->crypto_ctx.aes_ctx) + av_free(pls->crypto_ctx.aes_ctx); av_free(pls); } av_freep(&c->playlists); @@ -994,7 +1003,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int64_t n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1023,10 +1035,11 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); @@ -1041,6 +1054,8 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, *dts = ts; else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); +} else if (priv->datasize >= 8 && !strcmp(priv->owner, id3_priv_owner_audio_setup)) { +ff_hls_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); } } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; @@ -1084,7 +1099,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE; -parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta); +parse_id3(pls->ctx, pb, &metadata, ×tamp, &pls->audio_setup_info, &apic, &extra_meta); if (timestamp != AV_NOPTS_VALUE) { pls->id3_mpegts_timestamp = timestamp; @@ -1238,10 +1253,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %&q
[FFmpeg-devel] [PATCH 1/3] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of SAMPLE-AES decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 14 ++ libavcodec/adts_parser.c | 28 3 files changed, 43 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..e4454529c4 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..9ecd67fb5b 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,17 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..7df714e227 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 3/3] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 3cb3853c79..d612ebb185 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2028,23 +2028,23 @@ static int hls_read_header(AVFormatContext *s) break; } } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +goto fail; +} av_free(url); -goto fail; -} -av_free(url); } if (seg && seg->key_type == KEY_SAMPLE_AES) { @@ -2096,7 +2096,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) ret = ff_hls_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); else -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) goto fail; -- 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".
Re: [FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
Hello Steven, This patch enables SAMPLE-AES decryption for MPEG-TS format only and not for fragmented MP4 format. In the next version of the patch, I will add a check for it. Best Regards, Nachiket Tarate On Mon, Feb 1, 2021 at 12:48 PM Steven Liu wrote: > > > > 2021年1月28日 下午11:11,Nachiket Tarate 写道: > > > > Apple HTTP Live Streaming Sample Encryption: > > > > > https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption > > > > Signed-off-by: Nachiket Tarate > > --- > > libavformat/Makefile | 2 +- > > libavformat/hls.c| 101 +++-- > > libavformat/hls_sample_aes.c | 403 +++ > > libavformat/hls_sample_aes.h | 66 ++ > > libavformat/mpegts.c | 12 ++ > > 5 files changed, 568 insertions(+), 16 deletions(-) > > create mode 100644 libavformat/hls_sample_aes.c > > create mode 100644 libavformat/hls_sample_aes.h > > > > diff --git a/libavformat/Makefile b/libavformat/Makefile > > index 3a8fbcbe5f..c97930d98b 100644 > > --- a/libavformat/Makefile > > +++ b/libavformat/Makefile > > @@ -237,7 +237,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o > pcm.o > > OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o > > OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o > > OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o > > -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o > > +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o > > OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o > > OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o > > OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o > > diff --git a/libavformat/hls.c b/libavformat/hls.c > > index af2468ad9b..850068736e 100644 > > --- a/libavformat/hls.c > > +++ b/libavformat/hls.c > > @@ -2,6 +2,7 @@ > > * Apple HTTP Live Streaming demuxer > > * Copyright (c) 2010 Martin Storsjo > > * Copyright (c) 2013 Anssi Hannula > > + * Copyright (c) 2021 Nachiket Tarate > > * > > * This file is part of FFmpeg. > > * > > @@ -39,6 +40,8 @@ > > #include "avio_internal.h" > > #include "id3v2.h" > > > > +#include "hls_sample_aes.h" > > + > > #define INITIAL_BUFFER_SIZE 32768 > > > > #define MAX_FIELD_LEN 64 > > @@ -145,6 +148,10 @@ struct playlist { > > int id3_changed; /* ID3 tag data has changed at some point */ > > ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer > is opened */ > > > > +/* Used in case of SAMPLE-AES encryption method */ > > +HLSAudioSetupInfo audio_setup_info; > > +HLSCryptoContext crypto_ctx; > > + > > int64_t seek_timestamp; > > int seek_flags; > > int seek_stream_index; /* into subdemuxer stream array */ > > @@ -266,6 +273,8 @@ static void free_playlist_list(HLSContext *c) > > pls->ctx->pb = NULL; > > avformat_close_input(&pls->ctx); > > } > > +if (pls->crypto_ctx.aes_ctx) > > + av_free(pls->crypto_ctx.aes_ctx); > > av_free(pls); > > } > > av_freep(&c->playlists); > > @@ -994,7 +1003,10 @@ fail: > > > > static struct segment *current_segment(struct playlist *pls) > > { > > -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; > > +int64_t n = pls->cur_seq_no - pls->start_seq_no; > > +if (n >= pls->n_segments) > > +return NULL; > > +return pls->segments[n]; > > } > > > > static struct segment *next_segment(struct playlist *pls) > > @@ -1023,10 +1035,11 @@ static int read_from_url(struct playlist *pls, > struct segment *seg, > > > > /* Parse the raw ID3 data and pass contents to caller */ > > static void parse_id3(AVFormatContext *s, AVIOContext *pb, > > - AVDictionary **metadata, int64_t *dts, > > + AVDictionary **metadata, int64_t *dts, > HLSAudioSetupInfo *audio_setup_info, > > ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta > **extra_meta) > > { > > static const char id3_priv_owner_ts[] = > "com.apple.streaming.transportStreamTimestamp"; > > +static const char id3_priv_owner_audio_setup[] = > "com.apple.streaming.audioDescription"; > > ID3v2ExtraMeta *meta; > > > > ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); > > @@ -1041,7 +1
[FFmpeg-devel] [PATCH] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of SAMPLE-AES decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 14 ++ libavcodec/adts_parser.c | 28 3 files changed, 43 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..e4454529c4 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..9ecd67fb5b 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,17 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..7df714e227 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile | 2 +- libavformat/hls.c| 101 +++-- libavformat/hls_sample_aes.c | 403 +++ libavformat/hls_sample_aes.h | 66 ++ libavformat/mpegts.c | 12 ++ 5 files changed, 568 insertions(+), 16 deletions(-) create mode 100644 libavformat/hls_sample_aes.c create mode 100644 libavformat/hls_sample_aes.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 3a8fbcbe5f..c97930d98b 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -237,7 +237,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index af2468ad9b..850068736e 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_aes.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,10 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +/* Used in case of SAMPLE-AES encryption method */ +HLSAudioSetupInfo audio_setup_info; +HLSCryptoContext crypto_ctx; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -266,6 +273,8 @@ static void free_playlist_list(HLSContext *c) pls->ctx->pb = NULL; avformat_close_input(&pls->ctx); } +if (pls->crypto_ctx.aes_ctx) + av_free(pls->crypto_ctx.aes_ctx); av_free(pls); } av_freep(&c->playlists); @@ -994,7 +1003,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int64_t n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1023,10 +1035,11 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); @@ -1041,7 +1054,8 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, *dts = ts; else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); -} +} else if (priv->datasize >= 8 && !strcmp(priv->owner, id3_priv_owner_audio_setup)) +ff_hls_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; } @@ -1084,7 +1098,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE; -parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta); +parse_id3(pls->ctx, pb, &metadata, ×tamp, &pls->audio_setup_info, &apic, &extra_meta); if (timestamp != AV_NOPTS_VALUE) { pls->id3_mpegts_timestamp = timestamp; @@ -1238,10 +1252,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %&q
[FFmpeg-devel] [PATCH 1/3] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of SAMPLE-AES decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 14 ++ libavcodec/adts_parser.c | 28 3 files changed, 43 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..c6680b0fc8 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..9ecd67fb5b 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,17 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..7df714e227 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 3/3] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 850068736e..281842e10b 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2037,23 +2037,23 @@ static int hls_read_header(AVFormatContext *s) break; } } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +goto fail; +} av_free(url); -goto fail; -} -av_free(url); } pls->ctx->pb = &pls->pb; @@ -2088,7 +2088,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) ret = ff_hls_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); else -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) goto fail; -- 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".
[FFmpeg-devel] [PATCH 1/3] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of SAMPLE-AES encryption/decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 14 ++ libavcodec/adts_parser.c | 28 3 files changed, 43 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..c6680b0fc8 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..9ecd67fb5b 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,17 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..7df714e227 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 3/3] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 22e3b22650..c783bc7254 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2025,23 +2025,23 @@ static int hls_read_header(AVFormatContext *s) break; } } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +goto fail; +} av_free(url); -goto fail; -} -av_free(url); } pls->ctx->pb = &pls->pb; @@ -2076,7 +2076,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) ret = ff_hls_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); else -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) goto fail; -- 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".
[FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile | 2 +- libavformat/hls.c| 98 ++-- libavformat/hls_sample_aes.c | 463 +++ libavformat/hls_sample_aes.h | 64 + libavformat/mpegts.c | 12 + 5 files changed, 623 insertions(+), 16 deletions(-) create mode 100644 libavformat/hls_sample_aes.c create mode 100644 libavformat/hls_sample_aes.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 3a8fbcbe5f..c97930d98b 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -237,7 +237,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 619e4800de..22e3b22650 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_aes.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -986,7 +991,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1015,10 +1023,11 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); @@ -1033,7 +1042,8 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, *dts = ts; else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); -} +} else if (priv->datasize >= 8 && !strcmp(priv->owner, id3_priv_owner_audio_setup)) +ff_hls_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; } @@ -1076,7 +1086,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE; -parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta); +parse_id3(pls->ctx, pb, &metadata, ×tamp, &pls->audio_setup_info, &apic, &extra_meta); if (timestamp != AV_NOPTS_VALUE) { pls->id3_mpegts_timestamp = timestamp; @@ -1230,10 +1240,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n", seg->url, seg->url_offset, pls->index); -if (seg->key_type == KEY_NONE) { -ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http); -} else if (seg->key_type == KEY_AES_128) { -char iv[33], key[33], url[MAX_URL_SIZE]; +if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) {
[FFmpeg-devel] [PATCH 3/3] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 9e7f020cea..a2efa18b07 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2028,23 +2028,23 @@ static int hls_read_header(AVFormatContext *s) break; } } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +goto fail; +} av_free(url); -goto fail; -} -av_free(url); } pls->ctx->pb = &pls->pb; @@ -2079,7 +2079,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) { ret = ff_hls_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); } else { -ret = avformat_find_stream_info(pls->ctx, NULL); +ret = avformat_find_stream_info(pls->ctx, NULL); } if (ret < 0) goto fail; -- 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".
[FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile | 2 +- libavformat/hls.c| 97 ++- libavformat/hls_sample_aes.c | 486 +++ libavformat/hls_sample_aes.h | 64 + libavformat/mpegts.c | 12 + 5 files changed, 647 insertions(+), 14 deletions(-) create mode 100644 libavformat/hls_sample_aes.c create mode 100644 libavformat/hls_sample_aes.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 3a8fbcbe5f..c97930d98b 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -237,7 +237,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 619e4800de..9e7f020cea 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2021 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_aes.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -986,7 +991,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1015,10 +1023,11 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); @@ -1034,6 +1043,9 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); } +else if (priv->datasize >= 8 && !strcmp(priv->owner, id3_priv_owner_audio_setup)) { +ff_hls_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); +} } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; } @@ -1076,7 +1088,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE; -parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta); +parse_id3(pls->ctx, pb, &metadata, ×tamp, &pls->audio_setup_info, &apic, &extra_meta); if (timestamp != AV_NOPTS_VALUE) { pls->id3_mpegts_timestamp = timestamp; @@ -1230,10 +1242,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n", seg->url, seg->url_offset, pls->index); -if (seg->key_type == KEY_NONE) { -ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http); -} else if (seg->key_type == KEY_AES_128) { -char iv[33], key[33], url[MAX_URL_SIZE]; +if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) { if (strcmp(
[FFmpeg-devel] [PATCH 1/3] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of SAMPLE-AES encryption/decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 14 ++ libavcodec/adts_parser.c | 28 3 files changed, 43 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..c6680b0fc8 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..efdb5cdc15 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +48,17 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +/** + * Parse the ADTS frame header contained in the buffer, which is + * the first 54 bits. + * @param[in] buf Pointer to buffer containing the first 54 bits of the frame. + * @param[in] size Size of buffer containing the first 54 bits of the frame. + * @param[out] phdr Pointer to pointer to struct AACADTSHeaderInfo for which + * memory is allocated and header info is written into it. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_adts_header_parse (AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..2f10b9adcf 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -42,3 +42,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse (AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} -- 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".
[FFmpeg-devel] [PATCH 1/3] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of SAMPLE-AES encryption/decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 1 + libavcodec/adts_parser.c | 29 - libavcodec/adts_parser.h | 4 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..c6680b0fc8 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..c362ce46a5 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..3421d9fee8 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -21,7 +21,6 @@ #include #include -#include "adts_header.h" #include "adts_parser.h" int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) @@ -42,3 +41,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse (AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} diff --git a/libavcodec/adts_parser.h b/libavcodec/adts_parser.h index f85becd131..faa6e47426 100644 --- a/libavcodec/adts_parser.h +++ b/libavcodec/adts_parser.h @@ -22,6 +22,8 @@ #include #include +#include "adts_header.h" + #define AV_AAC_ADTS_HEADER_SIZE 7 /** @@ -34,4 +36,6 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames); +int avpriv_adts_header_parse (AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_PARSER_H */ -- 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".
[FFmpeg-devel] [PATCH 2/3] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile | 2 +- libavformat/hls.c| 97 ++- libavformat/hls_sample_aes.c | 497 +++ libavformat/hls_sample_aes.h | 64 + libavformat/mpegts.c | 12 + 5 files changed, 658 insertions(+), 14 deletions(-) create mode 100644 libavformat/hls_sample_aes.c create mode 100644 libavformat/hls_sample_aes.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 3a8fbcbe5f..c97930d98b 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -237,7 +237,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o avc.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 619e4800de..bc5247b8ce 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2020 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_aes.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -986,7 +991,10 @@ fail: static struct segment *current_segment(struct playlist *pls) { -return pls->segments[pls->cur_seq_no - pls->start_seq_no]; +int n = pls->cur_seq_no - pls->start_seq_no; +if (n >= pls->n_segments) +return NULL; +return pls->segments[n]; } static struct segment *next_segment(struct playlist *pls) @@ -1015,10 +1023,11 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); @@ -1034,6 +1043,9 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); } +else if (priv->datasize >= 8 && !strcmp(priv->owner, id3_priv_owner_audio_setup)) { +ff_hls_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); +} } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; } @@ -1076,7 +1088,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE; -parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta); +parse_id3(pls->ctx, pb, &metadata, ×tamp, &pls->audio_setup_info, &apic, &extra_meta); if (timestamp != AV_NOPTS_VALUE) { pls->id3_mpegts_timestamp = timestamp; @@ -1230,10 +1242,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n", seg->url, seg->url_offset, pls->index); -if (seg->key_type == KEY_NONE) { -ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http); -} else if (seg->key_type == KEY_AES_128) { -char iv[33], key[33], url[MAX_URL_SIZE]; +if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) { if (strcmp(
[FFmpeg-devel] [PATCH 3/3] libavformat/hls: correct indentation
Signed-off-by: Nachiket Tarate --- libavformat/hls.c | 38 +++--- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index bc5247b8ce..7d34f349c3 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2028,23 +2028,23 @@ static int hls_read_header(AVFormatContext *s) break; } } else { -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -pls->ctx->interrupt_callback = s->interrupt_callback; -url = av_strdup(pls->segments[0]->url); -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); -if (ret < 0) { -/* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ -av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); -avformat_free_context(pls->ctx); -pls->ctx = NULL; +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; +pls->ctx->interrupt_callback = s->interrupt_callback; +url = av_strdup(pls->segments[0]->url); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); +if (ret < 0) { +/* Free the ctx - it isn't initialized properly at this point, +* so avformat_close_input shouldn't be called. If +* avformat_open_input fails below, it frees and zeros the +* context, so it doesn't need any special treatment like this. */ +av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url); +avformat_free_context(pls->ctx); +pls->ctx = NULL; +av_free(url); +goto fail; +} av_free(url); -goto fail; -} -av_free(url); } pls->ctx->pb = &pls->pb; @@ -2079,9 +2079,9 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->nb_streams == 1) { ff_hls_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info); } else { -ret = avformat_find_stream_info(pls->ctx, NULL); -if (ret < 0) -goto fail; +ret = avformat_find_stream_info(pls->ctx, NULL); +if (ret < 0) +goto fail; } } -- 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".
Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
From: ffmpeg-devel on behalf of Steven Liu Sent: Tuesday, October 20, 2020 7:55 AM To: FFmpeg development discussions and patches Cc: Steven Liu Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer > 2020年10月19日 下午4:10,Nachiket Tarate 写道: > > > > > From: ffmpeg-devel on behalf of Steven Liu > > Sent: Monday, October 19, 2020 7:43 AM > To: FFmpeg development discussions and patches > Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for > SAMPLE-AES decryption in HLS demuxer > > Nachiket Tarate 于2020年10月18日周日 上午8:07写道: >> >> ___ >> From: ffmpeg-devel on behalf of Michael >> Niedermayer >> Sent: Thursday, October 15, 2020 11:35 PM >> To: FFmpeg development discussions and patches >> Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for >> SAMPLE-AES decryption in HLS demuxer >> >> On Thu, Oct 15, 2020 at 10:15:13PM +0530, Nachiket Tarate wrote: >>> Apple HTTP Live Streaming Sample Encryption: >>> >>> https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption >>> >>> Signed-off-by: Nachiket Tarate >>> --- >>> libavformat/Makefile | 2 +- >>> libavformat/hls.c| 93 ++- >>> libavformat/hls_sample_aes.c | 497 +++ >>> libavformat/hls_sample_aes.h | 64 + >>> libavformat/mpegts.c | 15 ++ >>> 5 files changed, 657 insertions(+), 14 deletions(-) >>> create mode 100644 libavformat/hls_sample_aes.c >>> create mode 100644 libavformat/hls_sample_aes.h >> >> This seems to break fate (segfault) >> I guess patchwork will notice it too but as i already tested and noticed ... >> >> --- ./tests/ref/fate/segment-mp4-to-ts 2020-10-10 18:08:06.500253003 +0200 >> +++ tests/data/fate/segment-mp4-to-ts 2020-10-15 20:03:24.586303460 +0200 >> @@ -128,5 +128,3 @@ >> 0, 428400, 435600, 3600, 156, 0xd2c3406c, F=0x0, S=1, >> 1, 0x00e000e0 >> 0, 432000, 439200, 3600, 330, 0x150d9b60, F=0x0, S=1, >> 1, 0x00e000e0 >> 0, 435600, 446400, 3600, 324, 0x558194ee, F=0x0, S=1, >> 1, 0x00e000e0 >> -0, 439200, 442800, 3600, 191, 0x108e54d1, F=0x0, S=1, >> 1, 0x00e000e0 >> -0, 442800, 45, 3600, 233, 0xac5b6486, F=0x0 >> Test segment-mp4-to-ts failed. Look at tests/data/fate/segment-mp4-to-ts.err >> for details. >> tests/Makefile:255: recipe for target 'fate-segment-mp4-to-ts' failed >> make: *** [fate-segment-mp4-to-ts] Error 139 >> >> >> I ran FATE with samples again but I didn't get segfault. Can you please help >> me to reproduce it ? > > https://patchwork.ffmpeg.org/project/ffmpeg/patch/sg2pr01mb269339627c977c841e26b05df2...@sg2pr01mb2693.apcprd01.prod.exchangelabs.com/ > fate failed message here. > > TESTsegment-mp4-to-ts > --- > /Users/liuqi/multimedia/upstream_ffmpeg/ffmpeg/tests/ref/fate/segment-mp4-to-ts > 2020-10-19 09:24:15.0 +0800 > +++ tests/data/fate/segment-mp4-to-ts 2020-10-19 10:09:43.0 +0800 > @@ -128,5 +128,3 @@ > 0, 428400, 435600, 3600, 156, 0xd2c3406c, F=0x0, > S=1,1, 0x00e000e0 > 0, 432000, 439200, 3600, 330, 0x150d9b60, F=0x0, > S=1,1, 0x00e000e0 > 0, 435600, 446400, 3600, 324, 0x558194ee, F=0x0, > S=1,1, 0x00e000e0 > -0, 439200, 442800, 3600, 191, 0x108e54d1, F=0x0, > S=1,1, 0x00e000e0 > -0, 442800, 45, 3600, 233, 0xac5b6486, F=0x0 > Test segment-mp4-to-ts failed. Look at > tests/data/fate/segment-mp4-to-ts.err for details. > make: *** [fate-segment-mp4-to-ts] Error 134 > (base) liuqi05:ufbuild liuqi$ history |grep make | tail -n 5 > 318 make -j6 > 319 make fate-rsync > 320 make fate > > (base) liuqi05:ufbuild liuqi$ ./ffmpeg > ffmpeg version N-99556-gf7e2f090ed Copyright (c) 2000-2020 the FFmpeg > developers > built with Apple clang version 12.0.0 (clang-1200.0.32.2) > configuration: --cc=clang --quiet --enable-htmlpages > --enable-libx264 --enable-libxml2 --enable-gpl --extra-ldflags='-O0 > -g3 -fsanitize=address -Wno-error -fPIC -I/usr/local/include' > --extra-ldflags='-O0 -g3 -fsanitize=address -Wno-error -fPIC > -L/usr/local/lib' --enable-libfreetype --enable-fontconfig > --enable-libspeex --enable-libopus --enable-libz
Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
From: ffmpeg-devel on behalf of Steven Liu Sent: Monday, October 19, 2020 3:17 PM To: FFmpeg development discussions and patches Cc: Steven Liu Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer > 2020年10月19日 下午4:10,Nachiket Tarate 写道: > > > > > From: ffmpeg-devel on behalf of Steven Liu > > Sent: Monday, October 19, 2020 7:43 AM > To: FFmpeg development discussions and patches > Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for > SAMPLE-AES decryption in HLS demuxer > > Nachiket Tarate 于2020年10月18日周日 上午8:07写道: >> >> ___ >> From: ffmpeg-devel on behalf of Michael >> Niedermayer >> Sent: Thursday, October 15, 2020 11:35 PM >> To: FFmpeg development discussions and patches >> Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for >> SAMPLE-AES decryption in HLS demuxer >> >> On Thu, Oct 15, 2020 at 10:15:13PM +0530, Nachiket Tarate wrote: >>> Apple HTTP Live Streaming Sample Encryption: >>> >>> https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption >>> >>> Signed-off-by: Nachiket Tarate >>> --- >>> libavformat/Makefile | 2 +- >>> libavformat/hls.c| 93 ++- >>> libavformat/hls_sample_aes.c | 497 +++ >>> libavformat/hls_sample_aes.h | 64 + >>> libavformat/mpegts.c | 15 ++ >>> 5 files changed, 657 insertions(+), 14 deletions(-) >>> create mode 100644 libavformat/hls_sample_aes.c >>> create mode 100644 libavformat/hls_sample_aes.h >> >> This seems to break fate (segfault) >> I guess patchwork will notice it too but as i already tested and noticed ... >> >> --- ./tests/ref/fate/segment-mp4-to-ts 2020-10-10 18:08:06.500253003 +0200 >> +++ tests/data/fate/segment-mp4-to-ts 2020-10-15 20:03:24.586303460 +0200 >> @@ -128,5 +128,3 @@ >> 0, 428400, 435600, 3600, 156, 0xd2c3406c, F=0x0, S=1, >> 1, 0x00e000e0 >> 0, 432000, 439200, 3600, 330, 0x150d9b60, F=0x0, S=1, >> 1, 0x00e000e0 >> 0, 435600, 446400, 3600, 324, 0x558194ee, F=0x0, S=1, >> 1, 0x00e000e0 >> -0, 439200, 442800, 3600, 191, 0x108e54d1, F=0x0, S=1, >> 1, 0x00e000e0 >> -0, 442800, 45, 3600, 233, 0xac5b6486, F=0x0 >> Test segment-mp4-to-ts failed. Look at tests/data/fate/segment-mp4-to-ts.err >> for details. >> tests/Makefile:255: recipe for target 'fate-segment-mp4-to-ts' failed >> make: *** [fate-segment-mp4-to-ts] Error 139 >> >> >> I ran FATE with samples again but I didn't get segfault. Can you please help >> me to reproduce it ? > > https://patchwork.ffmpeg.org/project/ffmpeg/patch/sg2pr01mb269339627c977c841e26b05df2...@sg2pr01mb2693.apcprd01.prod.exchangelabs.com/ > fate failed message here. > > TESTsegment-mp4-to-ts > --- > /Users/liuqi/multimedia/upstream_ffmpeg/ffmpeg/tests/ref/fate/segment-mp4-to-ts > 2020-10-19 09:24:15.0 +0800 > +++ tests/data/fate/segment-mp4-to-ts 2020-10-19 10:09:43.0 +0800 > @@ -128,5 +128,3 @@ > 0, 428400, 435600, 3600, 156, 0xd2c3406c, F=0x0, > S=1,1, 0x00e000e0 > 0, 432000, 439200, 3600, 330, 0x150d9b60, F=0x0, > S=1,1, 0x00e000e0 > 0, 435600, 446400, 3600, 324, 0x558194ee, F=0x0, > S=1,1, 0x00e000e0 > -0, 439200, 442800, 3600, 191, 0x108e54d1, F=0x0, > S=1,1, 0x00e000e0 > -0, 442800, 45, 3600, 233, 0xac5b6486, F=0x0 > Test segment-mp4-to-ts failed. Look at > tests/data/fate/segment-mp4-to-ts.err for details. > make: *** [fate-segment-mp4-to-ts] Error 134 > (base) liuqi05:ufbuild liuqi$ history |grep make | tail -n 5 > 318 make -j6 > 319 make fate-rsync > 320 make fate > > (base) liuqi05:ufbuild liuqi$ ./ffmpeg > ffmpeg version N-99556-gf7e2f090ed Copyright (c) 2000-2020 the FFmpeg > developers > built with Apple clang version 12.0.0 (clang-1200.0.32.2) > configuration: --cc=clang --quiet --enable-htmlpages > --enable-libx264 --enable-libxml2 --enable-gpl --extra-ldflags='-O0 > -g3 -fsanitize=address -Wno-error -fPIC -I/usr/local/include' > --extra-ldflags='-O0 -g3 -fsanitize=address -Wno-error -fPIC > -L/usr/local/lib' --enable-libfreetype --enable-fontconfig > --enable-libspeex --enable-libopus --enable
Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
From: ffmpeg-devel on behalf of Steven Liu Sent: Monday, October 19, 2020 7:43 AM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer Nachiket Tarate 于2020年10月18日周日 上午8:07写道: > > ___ > From: ffmpeg-devel on behalf of Michael > Niedermayer > Sent: Thursday, October 15, 2020 11:35 PM > To: FFmpeg development discussions and patches > Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for > SAMPLE-AES decryption in HLS demuxer > > On Thu, Oct 15, 2020 at 10:15:13PM +0530, Nachiket Tarate wrote: > > Apple HTTP Live Streaming Sample Encryption: > > > > https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption > > > > Signed-off-by: Nachiket Tarate > > --- > > libavformat/Makefile | 2 +- > > libavformat/hls.c| 93 ++- > > libavformat/hls_sample_aes.c | 497 +++ > > libavformat/hls_sample_aes.h | 64 + > > libavformat/mpegts.c | 15 ++ > > 5 files changed, 657 insertions(+), 14 deletions(-) > > create mode 100644 libavformat/hls_sample_aes.c > > create mode 100644 libavformat/hls_sample_aes.h > > This seems to break fate (segfault) > I guess patchwork will notice it too but as i already tested and noticed ... > > --- ./tests/ref/fate/segment-mp4-to-ts 2020-10-10 18:08:06.500253003 +0200 > +++ tests/data/fate/segment-mp4-to-ts 2020-10-15 20:03:24.586303460 +0200 > @@ -128,5 +128,3 @@ > 0, 428400, 435600, 3600, 156, 0xd2c3406c, F=0x0, S=1, > 1, 0x00e000e0 > 0, 432000, 439200, 3600, 330, 0x150d9b60, F=0x0, S=1, > 1, 0x00e000e0 > 0, 435600, 446400, 3600, 324, 0x558194ee, F=0x0, S=1, > 1, 0x00e000e0 > -0, 439200, 442800, 3600, 191, 0x108e54d1, F=0x0, S=1, > 1, 0x00e000e0 > -0, 442800, 45, 3600, 233, 0xac5b6486, F=0x0 > Test segment-mp4-to-ts failed. Look at tests/data/fate/segment-mp4-to-ts.err > for details. > tests/Makefile:255: recipe for target 'fate-segment-mp4-to-ts' failed > make: *** [fate-segment-mp4-to-ts] Error 139 > > > I ran FATE with samples again but I didn't get segfault. Can you please help > me to reproduce it ? https://patchwork.ffmpeg.org/project/ffmpeg/patch/sg2pr01mb269339627c977c841e26b05df2...@sg2pr01mb2693.apcprd01.prod.exchangelabs.com/ fate failed message here. TESTsegment-mp4-to-ts --- /Users/liuqi/multimedia/upstream_ffmpeg/ffmpeg/tests/ref/fate/segment-mp4-to-ts 2020-10-19 09:24:15.0 +0800 +++ tests/data/fate/segment-mp4-to-ts 2020-10-19 10:09:43.0 +0800 @@ -128,5 +128,3 @@ 0, 428400, 435600, 3600, 156, 0xd2c3406c, F=0x0, S=1,1, 0x00e000e0 0, 432000, 439200, 3600, 330, 0x150d9b60, F=0x0, S=1,1, 0x00e000e0 0, 435600, 446400, 3600, 324, 0x558194ee, F=0x0, S=1,1, 0x00e000e0 -0, 439200, 442800, 3600, 191, 0x108e54d1, F=0x0, S=1,1, 0x00e000e0 -0, 442800, 45, 3600, 233, 0xac5b6486, F=0x0 Test segment-mp4-to-ts failed. Look at tests/data/fate/segment-mp4-to-ts.err for details. make: *** [fate-segment-mp4-to-ts] Error 134 (base) liuqi05:ufbuild liuqi$ history |grep make | tail -n 5 318 make -j6 319 make fate-rsync 320 make fate (base) liuqi05:ufbuild liuqi$ ./ffmpeg ffmpeg version N-99556-gf7e2f090ed Copyright (c) 2000-2020 the FFmpeg developers built with Apple clang version 12.0.0 (clang-1200.0.32.2) configuration: --cc=clang --quiet --enable-htmlpages --enable-libx264 --enable-libxml2 --enable-gpl --extra-ldflags='-O0 -g3 -fsanitize=address -Wno-error -fPIC -I/usr/local/include' --extra-ldflags='-O0 -g3 -fsanitize=address -Wno-error -fPIC -L/usr/local/lib' --enable-libfreetype --enable-fontconfig --enable-libspeex --enable-libopus --enable-libzmq --enable-libx265 --enable-libass --enable-videotoolbox --disable-optimizations --enable-audiotoolbox --enable-opengl --disable-stripping --samples=../../fate-suite/ need use samples --samples=../../fate-suite/ and make fate-rsync after above two step, you can make fate reproduce it. Actually, I did make fate-rsync SAMPLES=fate-suite/ make fate SAMPLES=fate-suite/ It is same. But segmentation fault didn't occur while executing segment-mp4-to-ts. Any idea ? -- Best Regards, Nachiket Tarate ___ 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".
Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
___ From: ffmpeg-devel on behalf of Michael Niedermayer Sent: Thursday, October 15, 2020 11:35 PM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer On Thu, Oct 15, 2020 at 10:15:13PM +0530, Nachiket Tarate wrote: > Apple HTTP Live Streaming Sample Encryption: > > https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption > > Signed-off-by: Nachiket Tarate > --- > libavformat/Makefile | 2 +- > libavformat/hls.c| 93 ++- > libavformat/hls_sample_aes.c | 497 +++ > libavformat/hls_sample_aes.h | 64 + > libavformat/mpegts.c | 15 ++ > 5 files changed, 657 insertions(+), 14 deletions(-) > create mode 100644 libavformat/hls_sample_aes.c > create mode 100644 libavformat/hls_sample_aes.h This seems to break fate (segfault) I guess patchwork will notice it too but as i already tested and noticed ... --- ./tests/ref/fate/segment-mp4-to-ts 2020-10-10 18:08:06.500253003 +0200 +++ tests/data/fate/segment-mp4-to-ts 2020-10-15 20:03:24.586303460 +0200 @@ -128,5 +128,3 @@ 0, 428400, 435600, 3600, 156, 0xd2c3406c, F=0x0, S=1, 1, 0x00e000e0 0, 432000, 439200, 3600, 330, 0x150d9b60, F=0x0, S=1, 1, 0x00e000e0 0, 435600, 446400, 3600, 324, 0x558194ee, F=0x0, S=1, 1, 0x00e000e0 -0, 439200, 442800, 3600, 191, 0x108e54d1, F=0x0, S=1, 1, 0x00e000e0 -0, 442800, 45, 3600, 233, 0xac5b6486, F=0x0 Test segment-mp4-to-ts failed. Look at tests/data/fate/segment-mp4-to-ts.err for details. tests/Makefile:255: recipe for target 'fate-segment-mp4-to-ts' failed make: *** [fate-segment-mp4-to-ts] Error 139 I ran FATE with samples again but I didn't get segfault. Can you please help me to reproduce it ? -- Best Regards, Nachiket Tarate ___ 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".
[FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile | 2 +- libavformat/hls.c| 93 ++- libavformat/hls_sample_aes.c | 497 +++ libavformat/hls_sample_aes.h | 64 + libavformat/mpegts.c | 15 ++ 5 files changed, 657 insertions(+), 14 deletions(-) create mode 100644 libavformat/hls_sample_aes.c create mode 100644 libavformat/hls_sample_aes.h diff --git a/libavformat/Makefile b/libavformat/Makefile index a5e8bddb87..0ccec2d281 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -235,7 +235,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 72e28ab94f..63683e4742 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2020 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_aes.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -1015,10 +1020,11 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); @@ -1034,6 +1040,9 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); } +else if (priv->datasize >= 8 && !strcmp(priv->owner, id3_priv_owner_audio_setup)) { +ff_hls_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); +} } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; } @@ -1076,7 +1085,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE; -parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta); +parse_id3(pls->ctx, pb, &metadata, ×tamp, &pls->audio_setup_info, &apic, &extra_meta); if (timestamp != AV_NOPTS_VALUE) { pls->id3_mpegts_timestamp = timestamp; @@ -1230,10 +1239,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n", seg->url, seg->url_offset, pls->index); -if (seg->key_type == KEY_NONE) { -ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http); -} else if (seg->key_type == KEY_AES_128) { -char iv[33], key[33], url[MAX_URL_SIZE]; +if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) { if (strcmp(seg->key, pls->key_url)) { AVIOContext *pb = NULL; if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) { @@ -1249,6 +1255,10 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, } av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url)
Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
From: ffmpeg-devel on behalf of Carl Eugen Hoyos Sent: Monday, October 12, 2020 12:46 AM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer Am Sa., 10. Okt. 2020 um 17:01 Uhr schrieb Nachiket Tarate : > -pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; > -pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? > s->max_analyze_duration : 4 * AV_TIME_BASE; > -pls->ctx->interrupt_callback = s->interrupt_callback; > -url = av_strdup(pls->segments[0]->url); > -ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); > -av_free(url); > -if (ret < 0) { > -/* Free the ctx - it isn't initialized properly at this point, > - * so avformat_close_input shouldn't be called. If > - * avformat_open_input fails below, it frees and zeros the > - * context, so it doesn't need any special treatment like this. > */ > -av_log(s, AV_LOG_ERROR, "Error when loading first segment > '%s'\n", pls->segments[0]->url); > -avformat_free_context(pls->ctx); > -pls->ctx = NULL; > -goto fail; > +pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; > +pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? > s->max_analyze_duration : 4 * AV_TIME_BASE; > +pls->ctx->interrupt_callback = s->interrupt_callback; > +url = av_strdup(pls->segments[0]->url); > +ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); > +av_free(url); > +if (ret < 0) { > +/* Free the ctx - it isn't initialized properly at this > point, > +* so avformat_close_input shouldn't be called. If > +* avformat_open_input fails below, it frees and zeros the > +* context, so it doesn't need any special treatment like > this. */ > +av_log(s, AV_LOG_ERROR, "Error when loading first segment > '%s'\n", pls->segments[0]->url); > +avformat_free_context(pls->ctx); > +pls->ctx = NULL; > +goto fail; Please make the indentation change a separate patch. Nachiket > This is not just indentation change. The original code block has been moved under else. > +} > +else { Please merge these lines (several times in the patch). Nachiket > I will do this. Carl Eugen ___ 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". ___ 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".
Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
From: Nachiket Tarate Sent: Saturday, October 10, 2020 8:30 PM To: ffmpeg-devel@ffmpeg.org Subject: [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- + +static int get_next_adts_frame (AVParserContext *ctx, AudioFrame *frame) +{ +int ret = 0; + +AACADTSHeaderInfo *adts_hdr = NULL; + +/* Find next sync word 0xFFF */ +while (ctx->buf_in < ctx->buf_end - 1) { +if (*ctx->buf_in == 0xFF && *(ctx->buf_in + 1) & 0xF0 == 0xF0) +break; +ctx->buf_in++; +} + +if (ctx->buf_in >= ctx->buf_end - 1) { +return -1; +} + +frame->data = (uint8_t*)ctx->buf_in; + +ret = avpriv_adts_header_parse (&adts_hdr, frame->data, ctx->buf_end - frame->data); +if (ret < 0) { +return ret; +} + +frame->header_length = adts_hdr->crc_absent ? AV_AAC_ADTS_HEADER_SIZE : AV_AAC_ADTS_HEADER_SIZE + 2; +frame->length = adts_hdr->frame_length; + +av_free(adts_hdr); + +return 0; +} @Andreas Rheinhardt Here, frame_length field and avpriv_adts_header_parse() function are being used. -- Best Regards, Nachiket Tarate ___ 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".
Re: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
@Martin Storsj? If you get time, kindly review this patch. -- Best Regards, Nachiket Tarate From: ffmpeg-devel on behalf of Nachiket Tarate Sent: Saturday, October 10, 2020 8:30 PM To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile | 2 +- libavformat/hls.c| 132 ++--- libavformat/hls_sample_aes.c | 499 +++ libavformat/hls_sample_aes.h | 64 + libavformat/mpegts.c | 15 ++ 5 files changed, 679 insertions(+), 33 deletions(-) create mode 100644 libavformat/hls_sample_aes.c create mode 100644 libavformat/hls_sample_aes.h diff --git a/libavformat/Makefile b/libavformat/Makefile index a5e8bddb87..0ccec2d281 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -235,7 +235,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 72e28ab94f..3cdbc6dd94 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2020 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_aes.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -1015,10 +1020,11 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); @@ -1034,6 +1040,9 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); } +else if (priv->datasize >= 8 && !strcmp(priv->owner, id3_priv_owner_audio_setup)) { +ff_hls_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); +} } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; } @@ -1076,7 +1085,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE; -parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta); +parse_id3(pls->ctx, pb, &metadata, ×tamp, &pls->audio_setup_info, &apic, &extra_meta); if (timestamp != AV_NOPTS_VALUE) { pls->id3_mpegts_timestamp = timestamp; @@ -1230,10 +1239,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n", seg->url, seg->url_offset, pls->index); -if (seg->key_type == KEY_NONE) { -ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http); -} else if (seg->key_type == KEY_AES_128) { -char iv[33], key[33], url[MAX_URL_SIZE]; +if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) { if (strcmp(seg->key, pls->key
[FFmpeg-devel] [PATCH] libavformat/hls: add support for SAMPLE-AES decryption in HLS demuxer
Apple HTTP Live Streaming Sample Encryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption Signed-off-by: Nachiket Tarate --- libavformat/Makefile | 2 +- libavformat/hls.c| 132 ++--- libavformat/hls_sample_aes.c | 499 +++ libavformat/hls_sample_aes.h | 64 + libavformat/mpegts.c | 15 ++ 5 files changed, 679 insertions(+), 33 deletions(-) create mode 100644 libavformat/hls_sample_aes.c create mode 100644 libavformat/hls_sample_aes.h diff --git a/libavformat/Makefile b/libavformat/Makefile index a5e8bddb87..0ccec2d281 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -235,7 +235,7 @@ OBJS-$(CONFIG_HCOM_DEMUXER) += hcom.o pcm.o OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o OBJS-$(CONFIG_HEVC_MUXER)+= rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o +OBJS-$(CONFIG_HLS_DEMUXER) += hls.o hls_sample_aes.o OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o diff --git a/libavformat/hls.c b/libavformat/hls.c index 72e28ab94f..3cdbc6dd94 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2020 Nachiket Tarate * * This file is part of FFmpeg. * @@ -39,6 +40,8 @@ #include "avio_internal.h" #include "id3v2.h" +#include "hls_sample_aes.h" + #define INITIAL_BUFFER_SIZE 32768 #define MAX_FIELD_LEN 64 @@ -145,6 +148,8 @@ struct playlist { int id3_changed; /* ID3 tag data has changed at some point */ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */ +HLSAudioSetupInfo audio_setup_info; + int64_t seek_timestamp; int seek_flags; int seek_stream_index; /* into subdemuxer stream array */ @@ -1015,10 +1020,11 @@ static int read_from_url(struct playlist *pls, struct segment *seg, /* Parse the raw ID3 data and pass contents to caller */ static void parse_id3(AVFormatContext *s, AVIOContext *pb, - AVDictionary **metadata, int64_t *dts, + AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta) { static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp"; +static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription"; ID3v2ExtraMeta *meta; ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta); @@ -1034,6 +1040,9 @@ static void parse_id3(AVFormatContext *s, AVIOContext *pb, else av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts); } +else if (priv->datasize >= 8 && !strcmp(priv->owner, id3_priv_owner_audio_setup)) { +ff_hls_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize); +} } else if (!strcmp(meta->tag, "APIC") && apic) *apic = &meta->data.apic; } @@ -1076,7 +1085,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) ID3v2ExtraMeta *extra_meta = NULL; int64_t timestamp = AV_NOPTS_VALUE; -parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta); +parse_id3(pls->ctx, pb, &metadata, ×tamp, &pls->audio_setup_info, &apic, &extra_meta); if (timestamp != AV_NOPTS_VALUE) { pls->id3_mpegts_timestamp = timestamp; @@ -1230,10 +1239,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n", seg->url, seg->url_offset, pls->index); -if (seg->key_type == KEY_NONE) { -ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http); -} else if (seg->key_type == KEY_AES_128) { -char iv[33], key[33], url[MAX_URL_SIZE]; +if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) { if (strcmp(seg->key, pls->key_url)) { AVIOContext *pb = NULL; if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) { @@ -1249,6 +1255,10 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, } av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url)
Re: [FFmpeg-devel] [PATCH] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
From: ffmpeg-devel on behalf of Andreas Rheinhardt Sent: Friday, October 9, 2020 8:11 PM To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header Nachiket Tarate: > @James Almer > > Kindly merge this patch if it looks fine. > Can we see the supposed applications first? - Andreas Actually, I am adding support for SAMPLE-AES decryption in HLS demuxer. So, while decrypting AAC audio frames, frame_length is required. I will submit that patch in couple of days. Apple HTTP Live Streaming Sample Decryption: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption -- Nachiket Tarate ___ 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". ___ 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".
Re: [FFmpeg-devel] [PATCH] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
@James Almer Kindly merge this patch if it looks fine. -- Thanks & Regards, Nachiket Tarate From: ffmpeg-devel on behalf of Nachiket Tarate Sent: Thursday, October 8, 2020 8:02 PM To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header These will be used by HLS demuxer in case of SAMPLE-AES encryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 1 + libavcodec/adts_parser.c | 29 - libavcodec/adts_parser.h | 4 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..c6680b0fc8 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..c362ce46a5 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..7513b64181 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -21,7 +21,6 @@ #include #include -#include "adts_header.h" #include "adts_parser.h" int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) @@ -42,3 +41,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse (AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} diff --git a/libavcodec/adts_parser.h b/libavcodec/adts_parser.h index f85becd131..faa6e47426 100644 --- a/libavcodec/adts_parser.h +++ b/libavcodec/adts_parser.h @@ -22,6 +22,8 @@ #include #include +#include "adts_header.h" + #define AV_AAC_ADTS_HEADER_SIZE 7 /** @@ -34,4 +36,6 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames); +int avpriv_adts_header_parse (AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_PARSER_H */ -- 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". ___ 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".
[FFmpeg-devel] [PATCH] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer in case of SAMPLE-AES encryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 1 + libavcodec/adts_header.h | 1 + libavcodec/adts_parser.c | 29 - libavcodec/adts_parser.h | 4 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..c6680b0fc8 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -66,6 +66,7 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..c362ce46a5 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -34,6 +34,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c index 5c9f8ff6f2..7513b64181 100644 --- a/libavcodec/adts_parser.c +++ b/libavcodec/adts_parser.c @@ -21,7 +21,6 @@ #include #include -#include "adts_header.h" #include "adts_parser.h" int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) @@ -42,3 +41,31 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) return AVERROR(ENOSYS); #endif } + +int avpriv_adts_header_parse (AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +#if CONFIG_ADTS_HEADER +int ret = 0; +GetBitContext gb; + +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AACADTSHeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); + +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; + +ret = ff_adts_header_parse(&gb, *phdr); +if (ret < 0) +return ret; + +return 0; +#else +return AVERROR(ENOSYS); +#endif +} diff --git a/libavcodec/adts_parser.h b/libavcodec/adts_parser.h index f85becd131..faa6e47426 100644 --- a/libavcodec/adts_parser.h +++ b/libavcodec/adts_parser.h @@ -22,6 +22,8 @@ #include #include +#include "adts_header.h" + #define AV_AAC_ADTS_HEADER_SIZE 7 /** @@ -34,4 +36,6 @@ int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames); +int avpriv_adts_header_parse (AACADTSHeaderInfo **phdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_PARSER_H */ -- 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".
Re: [FFmpeg-devel] [PATCH] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
From: ffmpeg-devel on behalf of James Almer Sent: Tuesday, October 6, 2020 8:47 PM To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header On 10/6/2020 11:30 AM, Nachiket Tarate wrote: > These will be used by HLS demuxer for SAMPLE-AES decryption. > > Signed-off-by: Nachiket Tarate > --- > libavcodec/adts_header.c | 18 ++ > libavcodec/adts_header.h | 4 > 2 files changed, 22 insertions(+) > > diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c > index 0889820f8a..006455b110 100644 > --- a/libavcodec/adts_header.c > +++ b/libavcodec/adts_header.c > @@ -3,6 +3,7 @@ > * Copyright (c) 2003 Fabrice Bellard > * Copyright (c) 2003 Michael Niedermayer > * Copyright (c) 2009 Alex Converse > + * Copyright (c) 2020 Nachiket Tarate > * > * This file is part of FFmpeg. > * > @@ -66,6 +67,23 @@ int ff_adts_header_parse(GetBitContext *gbc, > AACADTSHeaderInfo *hdr) > hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; > hdr->samples= (rdb + 1) * 1024; > hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; > +hdr->frame_length= size; > > return size; > } > + > +int avpriv_adts_header_parse (AACADTSHeaderInfo *hdr, const uint8_t *buf, > size_t size) You're making sizeof(AACADTSHeaderInfo) part of the ABI this way, which is not desirable. If you look at avpriv_ac3_parse_header(), it takes a pointer to pointer to AC3HeaderInfo, and allocates it if needed. Also, you should instead add this function to adts_parser.c and make it return AVERROR(ENOSYS) when CONFIG_ADTS_HEADER is 0. This is done so the symbol is always present even when the functionality is not. Nachiket> I will do these changes and resubmit the patch. I assume you're adding this function because you need AACADTSHeaderInfo fields that av_adts_header_parse() alone does not provide, like frame_length? Nachiket > Yes. Your understanding is correct. > +{ > +int ret = 0; > +GetBitContext gb; > +if (size < AV_AAC_ADTS_HEADER_SIZE) > +return AVERROR_INVALIDDATA; > +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); > +if (ret < 0) > +return ret; > +ret = ff_adts_header_parse(&gb, hdr); > +if (ret < 0) > +return ret; > +return 0; > +} > + > diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h > index f615f6a9f9..d33bd61818 100644 > --- a/libavcodec/adts_header.h > +++ b/libavcodec/adts_header.h > @@ -2,6 +2,7 @@ > * AAC ADTS header decoding prototypes and structures > * Copyright (c) 2003 Fabrice Bellard > * Copyright (c) 2003 Michael Niedermayer > + * Copyright (c) 2020 Nachiket Tarate > * > * This file is part of FFmpeg. > * > @@ -34,6 +35,7 @@ typedef struct AACADTSHeaderInfo { > uint8_t sampling_index; > uint8_t chan_config; > uint8_t num_aac_frames; > +uint32_t frame_length; > } AACADTSHeaderInfo; > > /** > @@ -47,4 +49,6 @@ typedef struct AACADTSHeaderInfo { > */ > int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); > > +int avpriv_adts_header_parse (AACADTSHeaderInfo *hdr, const uint8_t *buf, > size_t size); > + > #endif /* AVCODEC_ADTS_HEADER_H */ > ___ 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". ___ 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".
[FFmpeg-devel] [PATCH] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer for SAMPLE-AES decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 18 ++ libavcodec/adts_header.h | 4 2 files changed, 22 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..006455b110 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -3,6 +3,7 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2009 Alex Converse + * Copyright (c) 2020 Nachiket Tarate * * This file is part of FFmpeg. * @@ -66,6 +67,23 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } + +int avpriv_adts_header_parse (AACADTSHeaderInfo *hdr, const uint8_t *buf, size_t size) +{ +int ret = 0; +GetBitContext gb; +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; +ret = ff_adts_header_parse(&gb, hdr); +if (ret < 0) +return ret; +return 0; +} + diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..d33bd61818 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -2,6 +2,7 @@ * AAC ADTS header decoding prototypes and structures * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2020 Nachiket Tarate * * This file is part of FFmpeg. * @@ -34,6 +35,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +49,6 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +int avpriv_adts_header_parse (AACADTSHeaderInfo *hdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ -- 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".
Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3tab: rename ff_ac3_sample_rate_tab to avpriv_ac3_sample_rate_tab so that it can be used in libavformat
From: ffmpeg-devel on behalf of Anton Khirnov Sent: Monday, October 5, 2020 1:50 PM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3tab: rename ff_ac3_sample_rate_tab to avpriv_ac3_sample_rate_tab so that it can be used in libavformat Quoting Nachiket Tarate (2020-10-04 16:35:09) > This will be used by HLS demuxer to parse EC3SpecificBox (dec3) during > SAMPLE-AES decryption. > > Signed-off-by: Nachiket Tarate Since the table is so small, it seems preferable to duplicate it in libavformat than add eat another private symbol. Private symbols are evil and should not exist. -- Anton Khirnov @Anton Khirnov In the first version of the patch, I had implemented avpriv_eac3_parse_dec3() function in ac3_parser.c to avoid sharing or duplication of table across the libraries. I changed that implementation based on James Almer 's review comments. @James Almer What is your opinion about Anton Khirnov 's review comments ? -- Nachiket Tarate ___ 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". ___ 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".
[FFmpeg-devel] [PATCH 2/2] libavcodec/ac3tab: rename ff_ac3_sample_rate_tab to avpriv_ac3_sample_rate_tab so that it can be used in libavformat
This will be used by HLS demuxer to parse EC3SpecificBox (dec3) during SAMPLE-AES decryption. Signed-off-by: Nachiket Tarate --- libavcodec/ac3_parser.c | 6 +++--- libavcodec/ac3enc.c | 2 +- libavcodec/ac3enc_fixed.c | 2 +- libavcodec/ac3enc_float.c | 2 +- libavcodec/ac3tab.c | 2 +- libavcodec/ac3tab.h | 2 +- libavcodec/eac3enc.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index ba171653ef..1c08c5f2b5 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -102,7 +102,7 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) hdr->lfe_on = get_bits1(gbc); hdr->sr_shift = FFMAX(hdr->bitstream_id, 8) - 8; -hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift; +hdr->sample_rate = avpriv_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift; hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift; hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2; @@ -126,11 +126,11 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) int sr_code2 = get_bits(gbc, 2); if(sr_code2 == 3) return AAC_AC3_PARSE_ERROR_SAMPLE_RATE; -hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2; +hdr->sample_rate = avpriv_ac3_sample_rate_tab[sr_code2] / 2; hdr->sr_shift = 1; } else { hdr->num_blocks = eac3_blocks[get_bits(gbc, 2)]; -hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code]; +hdr->sample_rate = avpriv_ac3_sample_rate_tab[hdr->sr_code]; hdr->sr_shift = 0; } diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index 37dc0fb2ef..914fc5e5be 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -2128,7 +2128,7 @@ static av_cold int validate_options(AC3EncodeContext *s) the generated files are correct. */ max_sr = s->eac3 ? 2 : 8; for (i = 0; i <= max_sr; i++) { -if ((ff_ac3_sample_rate_tab[i % 3] >> (i / 3)) == avctx->sample_rate) +if ((avpriv_ac3_sample_rate_tab[i % 3] >> (i / 3)) == avctx->sample_rate) break; } if (i > max_sr) { diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index 428bbfb3c5..82829c12dc 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -156,7 +156,7 @@ AVCodec ff_ac3_fixed_encoder = { AV_SAMPLE_FMT_NONE }, .priv_class = &ac3enc_class, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, -.supported_samplerates = ff_ac3_sample_rate_tab, +.supported_samplerates = avpriv_ac3_sample_rate_tab, .channel_layouts = ff_ac3_channel_layouts, .defaults= ac3_defaults, }; diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index 99863a9722..80478878f7 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -150,7 +150,7 @@ AVCodec ff_ac3_encoder = { .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .priv_class = &ac3enc_class, -.supported_samplerates = ff_ac3_sample_rate_tab, +.supported_samplerates = avpriv_ac3_sample_rate_tab, .channel_layouts = ff_ac3_channel_layouts, .defaults= ac3_defaults, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c index ef2a41bc59..215fd18000 100644 --- a/libavcodec/ac3tab.c +++ b/libavcodec/ac3tab.c @@ -126,7 +126,7 @@ const uint8_t ff_ac3_dec_channel_map[8][2][6] = { }; /* possible frequencies */ -const int ff_ac3_sample_rate_tab[] = { 48000, 44100, 32000, 0 }; +const int avpriv_ac3_sample_rate_tab[] = { 48000, 44100, 32000, 0 }; /* possible bitrates */ const uint16_t ff_ac3_bitrate_tab[19] = { diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h index 1d1264e3fc..dec2f11abd 100644 --- a/libavcodec/ac3tab.h +++ b/libavcodec/ac3tab.h @@ -33,7 +33,7 @@ extern const uint8_t ff_ac3_channels_tab[8]; extern av_export_avcodec const uint16_t avpriv_ac3_channel_layout_tab[8]; extern const uint8_t ff_ac3_enc_channel_map[8][2][6]; extern const uint8_t ff_ac3_dec_channel_map[8][2][6]; -extern const int ff_ac3_sample_rate_tab[]; +extern av_export_avcodec const int avpriv_ac3_sample_rate_tab[]; extern const uint16_t ff_ac3_bitrate_tab[19]; extern const uint8_t ff_ac3_rematrix_band_tab[5]; extern const uint8_t ff_eac3_default_cpl_band_struct[18]; diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c index 8e1032f268..7cf
[FFmpeg-devel] [PATCH 2/2] libavcodec/ac3tab: rename ff_ac3_sample_rate_tab to avpriv_ac3_sample_rate_tab so that it can be used in libavformat
This will be used by HLS demuxer to parse EC3SpecificBox (dec3) during SAMPLE-AES decryption. Signed-off-by: Nachiket Tarate --- libavcodec/ac3_parser.c | 6 +++--- libavcodec/ac3enc.c | 2 +- libavcodec/ac3enc_fixed.c | 2 +- libavcodec/ac3enc_float.c | 2 +- libavcodec/ac3tab.c | 2 +- libavcodec/ac3tab.h | 2 +- libavcodec/eac3enc.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index ba171653ef..1c08c5f2b5 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -102,7 +102,7 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) hdr->lfe_on = get_bits1(gbc); hdr->sr_shift = FFMAX(hdr->bitstream_id, 8) - 8; -hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift; +hdr->sample_rate = avpriv_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift; hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift; hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2; @@ -126,11 +126,11 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) int sr_code2 = get_bits(gbc, 2); if(sr_code2 == 3) return AAC_AC3_PARSE_ERROR_SAMPLE_RATE; -hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2; +hdr->sample_rate = avpriv_ac3_sample_rate_tab[sr_code2] / 2; hdr->sr_shift = 1; } else { hdr->num_blocks = eac3_blocks[get_bits(gbc, 2)]; -hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code]; +hdr->sample_rate = avpriv_ac3_sample_rate_tab[hdr->sr_code]; hdr->sr_shift = 0; } diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index 37dc0fb2ef..914fc5e5be 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -2128,7 +2128,7 @@ static av_cold int validate_options(AC3EncodeContext *s) the generated files are correct. */ max_sr = s->eac3 ? 2 : 8; for (i = 0; i <= max_sr; i++) { -if ((ff_ac3_sample_rate_tab[i % 3] >> (i / 3)) == avctx->sample_rate) +if ((avpriv_ac3_sample_rate_tab[i % 3] >> (i / 3)) == avctx->sample_rate) break; } if (i > max_sr) { diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index 428bbfb3c5..82829c12dc 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -156,7 +156,7 @@ AVCodec ff_ac3_fixed_encoder = { AV_SAMPLE_FMT_NONE }, .priv_class = &ac3enc_class, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, -.supported_samplerates = ff_ac3_sample_rate_tab, +.supported_samplerates = avpriv_ac3_sample_rate_tab, .channel_layouts = ff_ac3_channel_layouts, .defaults= ac3_defaults, }; diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index 99863a9722..80478878f7 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -150,7 +150,7 @@ AVCodec ff_ac3_encoder = { .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .priv_class = &ac3enc_class, -.supported_samplerates = ff_ac3_sample_rate_tab, +.supported_samplerates = avpriv_ac3_sample_rate_tab, .channel_layouts = ff_ac3_channel_layouts, .defaults= ac3_defaults, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c index ef2a41bc59..215fd18000 100644 --- a/libavcodec/ac3tab.c +++ b/libavcodec/ac3tab.c @@ -126,7 +126,7 @@ const uint8_t ff_ac3_dec_channel_map[8][2][6] = { }; /* possible frequencies */ -const int ff_ac3_sample_rate_tab[] = { 48000, 44100, 32000, 0 }; +const int avpriv_ac3_sample_rate_tab[] = { 48000, 44100, 32000, 0 }; /* possible bitrates */ const uint16_t ff_ac3_bitrate_tab[19] = { diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h index 1d1264e3fc..b656d7e39b 100644 --- a/libavcodec/ac3tab.h +++ b/libavcodec/ac3tab.h @@ -33,7 +33,7 @@ extern const uint8_t ff_ac3_channels_tab[8]; extern av_export_avcodec const uint16_t avpriv_ac3_channel_layout_tab[8]; extern const uint8_t ff_ac3_enc_channel_map[8][2][6]; extern const uint8_t ff_ac3_dec_channel_map[8][2][6]; -extern const int ff_ac3_sample_rate_tab[]; +extern const int avpriv_ac3_sample_rate_tab[]; extern const uint16_t ff_ac3_bitrate_tab[19]; extern const uint8_t ff_ac3_rematrix_band_tab[5]; extern const uint8_t ff_eac3_default_cpl_band_struct[18]; diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c index 8e1032f268..7cf7d62fab 100644 ---
Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv function to parse EC3SpecificBox (dec3)
From: ffmpeg-devel on behalf of James Almer Sent: Sunday, October 4, 2020 3:07 AM To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv function to parse EC3SpecificBox (dec3) On 10/3/2020 6:12 PM, Nachiket Tarate wrote: > So you want me to change ff_ac3_sample_rate_tab to avpriv_ac3_sample_rate_tab > and get channel count using av_get_channel_layout_nb_channels(). Is my > understanding correct ? Yes. Also please, don't top post in this list. Write below the paragraph you're replying to. Okay, Thanks ! I will resubmit this patch. Meanwhile, will you please review my first patch: [PATCH 1/2] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header ? > > From: ffmpeg-devel on behalf of James Almer > > Sent: Saturday, October 3, 2020 11:04 PM > To: ffmpeg-devel@ffmpeg.org > Subject: Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv > function to parse EC3SpecificBox (dec3) > > On 10/3/2020 2:30 PM, Nachiket Tarate wrote: >> Actually names of 2 tables ff_ac3_sample_rate_tab and ff_ac3_channels_tab >> need to be changed in order to access them from libavformat. >> There would be changes in multiple files in which these tables have been >> used currently. Is that fine ? > > You can use av_get_channel_layout_nb_channels() to get channel count > from the output of avpriv_ac3_channel_layout_tab[]. Same as > mov_read_dec3() in libavformat/mov.c does. > >> >> >> From: ffmpeg-devel on behalf of James >> Almer >> Sent: Friday, October 2, 2020 7:48 PM >> To: ffmpeg-devel@ffmpeg.org >> Subject: Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv >> function to parse EC3SpecificBox (dec3) >> >> On 10/2/2020 10:10 AM, Nachiket Tarate wrote: >>> This will be used by HLS demuxer for SAMPLE-AES decryption. >>> >>> Signed-off-by: Nachiket Tarate >>> --- >>> libavcodec/ac3_parser.c | 47 >>> libavcodec/ac3_parser_internal.h | 4 +++ >>> 2 files changed, 51 insertions(+) >>> >>> diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c >>> index ba171653ef..a8fdde0ff9 100644 >>> --- a/libavcodec/ac3_parser.c >>> +++ b/libavcodec/ac3_parser.c >>> @@ -2,6 +2,7 @@ >>> * AC-3 parser >>> * Copyright (c) 2003 Fabrice Bellard >>> * Copyright (c) 2003 Michael Niedermayer >>> + * Copyright (c) 2020 Nachiket Tarate >>> * >>> * This file is part of FFmpeg. >>> * >>> @@ -172,6 +173,47 @@ int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, >>> const uint8_t *buf, >>> return get_bits_count(&gb); >>> } >>> >>> +/* >>> + * Parse 'dec3' EC3SpecificBox >>> + */ >>> +int avpriv_eac3_parse_dec3(AC3HeaderInfo **phdr, const uint8_t *buf, >>> size_t size) >>> +{ >>> +GetBitContext gb; >>> +AC3HeaderInfo *hdr; >>> +int err; >>> + >>> +int data_rate, fscod, acmod, lfeon; >>> + >>> +if (!*phdr) >>> +*phdr = av_mallocz(sizeof(AC3HeaderInfo)); >>> +if (!*phdr) >>> +return AVERROR(ENOMEM); >>> +hdr = *phdr; >>> + >>> +err = init_get_bits8(&gb, buf, size); >>> +if (err < 0) >>> +return AVERROR_INVALIDDATA; >>> + >>> +data_rate = get_bits(&gb, 13); >>> +skip_bits(&gb, 3); >>> +fscod = get_bits(&gb, 2); >>> +skip_bits(&gb, 10); >>> +acmod = get_bits(&gb, 3); >>> +lfeon = get_bits(&gb, 1); >>> + >>> +hdr->sample_rate = ff_ac3_sample_rate_tab[fscod]; >> >> Why not instead just make this array avpriv_? Everything else can be >> done within libavformat. See mov_read_dec3() in mov.c >> >>> + >>> +hdr->channels = ff_ac3_channels_tab[acmod] + lfeon; >>> + >>> +hdr->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; >>> +if (lfeon) >>> +hdr->channel_layout |= AV_CH_LOW_FREQUENCY; >>> + >>> +hdr->bit_rate = data_rate*1000; >>> + >>> +return 0; >>> +} >>> + >>> int av_ac3_parse_header(const uint8_t *buf, size_t size, >>> uint8_t *bitstream_id, uint16_t *frame_size) >>> { >
Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv function to parse EC3SpecificBox (dec3)
So you want me to change ff_ac3_sample_rate_tab to avpriv_ac3_sample_rate_tab and get channel count using av_get_channel_layout_nb_channels(). Is my understanding correct ? From: ffmpeg-devel on behalf of James Almer Sent: Saturday, October 3, 2020 11:04 PM To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv function to parse EC3SpecificBox (dec3) On 10/3/2020 2:30 PM, Nachiket Tarate wrote: > Actually names of 2 tables ff_ac3_sample_rate_tab and ff_ac3_channels_tab > need to be changed in order to access them from libavformat. > There would be changes in multiple files in which these tables have been used > currently. Is that fine ? You can use av_get_channel_layout_nb_channels() to get channel count from the output of avpriv_ac3_channel_layout_tab[]. Same as mov_read_dec3() in libavformat/mov.c does. > > > From: ffmpeg-devel on behalf of James Almer > > Sent: Friday, October 2, 2020 7:48 PM > To: ffmpeg-devel@ffmpeg.org > Subject: Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv > function to parse EC3SpecificBox (dec3) > > On 10/2/2020 10:10 AM, Nachiket Tarate wrote: >> This will be used by HLS demuxer for SAMPLE-AES decryption. >> >> Signed-off-by: Nachiket Tarate >> --- >> libavcodec/ac3_parser.c | 47 >> libavcodec/ac3_parser_internal.h | 4 +++ >> 2 files changed, 51 insertions(+) >> >> diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c >> index ba171653ef..a8fdde0ff9 100644 >> --- a/libavcodec/ac3_parser.c >> +++ b/libavcodec/ac3_parser.c >> @@ -2,6 +2,7 @@ >> * AC-3 parser >> * Copyright (c) 2003 Fabrice Bellard >> * Copyright (c) 2003 Michael Niedermayer >> + * Copyright (c) 2020 Nachiket Tarate >> * >> * This file is part of FFmpeg. >> * >> @@ -172,6 +173,47 @@ int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const >> uint8_t *buf, >> return get_bits_count(&gb); >> } >> >> +/* >> + * Parse 'dec3' EC3SpecificBox >> + */ >> +int avpriv_eac3_parse_dec3(AC3HeaderInfo **phdr, const uint8_t *buf, size_t >> size) >> +{ >> +GetBitContext gb; >> +AC3HeaderInfo *hdr; >> +int err; >> + >> +int data_rate, fscod, acmod, lfeon; >> + >> +if (!*phdr) >> +*phdr = av_mallocz(sizeof(AC3HeaderInfo)); >> +if (!*phdr) >> +return AVERROR(ENOMEM); >> +hdr = *phdr; >> + >> +err = init_get_bits8(&gb, buf, size); >> +if (err < 0) >> +return AVERROR_INVALIDDATA; >> + >> +data_rate = get_bits(&gb, 13); >> +skip_bits(&gb, 3); >> +fscod = get_bits(&gb, 2); >> +skip_bits(&gb, 10); >> +acmod = get_bits(&gb, 3); >> +lfeon = get_bits(&gb, 1); >> + >> +hdr->sample_rate = ff_ac3_sample_rate_tab[fscod]; > > Why not instead just make this array avpriv_? Everything else can be > done within libavformat. See mov_read_dec3() in mov.c > >> + >> +hdr->channels = ff_ac3_channels_tab[acmod] + lfeon; >> + >> +hdr->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; >> +if (lfeon) >> +hdr->channel_layout |= AV_CH_LOW_FREQUENCY; >> + >> +hdr->bit_rate = data_rate*1000; >> + >> +return 0; >> +} >> + >> int av_ac3_parse_header(const uint8_t *buf, size_t size, >> uint8_t *bitstream_id, uint16_t *frame_size) >> { >> @@ -256,6 +298,11 @@ int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const >> uint8_t *buf, >> return AVERROR(ENOSYS); >> } >> >> +int avpriv_eac3_parse_dec3(AC3HeaderInfo **phdr, const uint8_t *buf, size_t >> size) >> +{ >> +return AVERROR(ENOSYS); >> +} >> + >> int av_ac3_parse_header(const uint8_t *buf, size_t size, >> uint8_t *bitstream_id, uint16_t *frame_size) >> { >> diff --git a/libavcodec/ac3_parser_internal.h >> b/libavcodec/ac3_parser_internal.h >> index 3648802a73..0388a5bb5e 100644 >> --- a/libavcodec/ac3_parser_internal.h >> +++ b/libavcodec/ac3_parser_internal.h >> @@ -38,5 +38,9 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo >> *hdr); >> >> int avpriv_ac3_parse_header(AC3HeaderInfo **hdr, const uint8_t *buf, >> size_t size); >> +/* >> + * Parse 'dec3&
Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv function to parse EC3SpecificBox (dec3)
Actually names of 2 tables ff_ac3_sample_rate_tab and ff_ac3_channels_tab need to be changed in order to access them from libavformat. There would be changes in multiple files in which these tables have been used currently. Is that fine ? From: ffmpeg-devel on behalf of James Almer Sent: Friday, October 2, 2020 7:48 PM To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv function to parse EC3SpecificBox (dec3) On 10/2/2020 10:10 AM, Nachiket Tarate wrote: > This will be used by HLS demuxer for SAMPLE-AES decryption. > > Signed-off-by: Nachiket Tarate > --- > libavcodec/ac3_parser.c | 47 > libavcodec/ac3_parser_internal.h | 4 +++ > 2 files changed, 51 insertions(+) > > diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c > index ba171653ef..a8fdde0ff9 100644 > --- a/libavcodec/ac3_parser.c > +++ b/libavcodec/ac3_parser.c > @@ -2,6 +2,7 @@ > * AC-3 parser > * Copyright (c) 2003 Fabrice Bellard > * Copyright (c) 2003 Michael Niedermayer > + * Copyright (c) 2020 Nachiket Tarate > * > * This file is part of FFmpeg. > * > @@ -172,6 +173,47 @@ int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const > uint8_t *buf, > return get_bits_count(&gb); > } > > +/* > + * Parse 'dec3' EC3SpecificBox > + */ > +int avpriv_eac3_parse_dec3(AC3HeaderInfo **phdr, const uint8_t *buf, size_t > size) > +{ > +GetBitContext gb; > +AC3HeaderInfo *hdr; > +int err; > + > +int data_rate, fscod, acmod, lfeon; > + > +if (!*phdr) > +*phdr = av_mallocz(sizeof(AC3HeaderInfo)); > +if (!*phdr) > +return AVERROR(ENOMEM); > +hdr = *phdr; > + > +err = init_get_bits8(&gb, buf, size); > +if (err < 0) > +return AVERROR_INVALIDDATA; > + > +data_rate = get_bits(&gb, 13); > +skip_bits(&gb, 3); > +fscod = get_bits(&gb, 2); > +skip_bits(&gb, 10); > +acmod = get_bits(&gb, 3); > +lfeon = get_bits(&gb, 1); > + > +hdr->sample_rate = ff_ac3_sample_rate_tab[fscod]; Why not instead just make this array avpriv_? Everything else can be done within libavformat. See mov_read_dec3() in mov.c > + > +hdr->channels = ff_ac3_channels_tab[acmod] + lfeon; > + > +hdr->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; > +if (lfeon) > +hdr->channel_layout |= AV_CH_LOW_FREQUENCY; > + > +hdr->bit_rate = data_rate*1000; > + > +return 0; > +} > + > int av_ac3_parse_header(const uint8_t *buf, size_t size, > uint8_t *bitstream_id, uint16_t *frame_size) > { > @@ -256,6 +298,11 @@ int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const > uint8_t *buf, > return AVERROR(ENOSYS); > } > > +int avpriv_eac3_parse_dec3(AC3HeaderInfo **phdr, const uint8_t *buf, size_t > size) > +{ > +return AVERROR(ENOSYS); > +} > + > int av_ac3_parse_header(const uint8_t *buf, size_t size, > uint8_t *bitstream_id, uint16_t *frame_size) > { > diff --git a/libavcodec/ac3_parser_internal.h > b/libavcodec/ac3_parser_internal.h > index 3648802a73..0388a5bb5e 100644 > --- a/libavcodec/ac3_parser_internal.h > +++ b/libavcodec/ac3_parser_internal.h > @@ -38,5 +38,9 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo > *hdr); > > int avpriv_ac3_parse_header(AC3HeaderInfo **hdr, const uint8_t *buf, > size_t size); > +/* > + * Parse 'dec3' EC3SpecificBox > + */ > +int avpriv_eac3_parse_dec3(AC3HeaderInfo **phdr, const uint8_t *buf, size_t > size); > > #endif /* AVCODEC_AC3_PARSER_INTERNAL_H */ > ___ 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". ___ 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".
[FFmpeg-devel] [PATCH 2/2] libavcodec/ac3_parser: add avpriv function to parse EC3SpecificBox (dec3)
This will be used by HLS demuxer for SAMPLE-AES decryption. Signed-off-by: Nachiket Tarate --- libavcodec/ac3_parser.c | 47 libavcodec/ac3_parser_internal.h | 4 +++ 2 files changed, 51 insertions(+) diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index ba171653ef..a8fdde0ff9 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -2,6 +2,7 @@ * AC-3 parser * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2020 Nachiket Tarate * * This file is part of FFmpeg. * @@ -172,6 +173,47 @@ int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const uint8_t *buf, return get_bits_count(&gb); } +/* + * Parse 'dec3' EC3SpecificBox + */ +int avpriv_eac3_parse_dec3(AC3HeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +GetBitContext gb; +AC3HeaderInfo *hdr; +int err; + +int data_rate, fscod, acmod, lfeon; + +if (!*phdr) +*phdr = av_mallocz(sizeof(AC3HeaderInfo)); +if (!*phdr) +return AVERROR(ENOMEM); +hdr = *phdr; + +err = init_get_bits8(&gb, buf, size); +if (err < 0) +return AVERROR_INVALIDDATA; + +data_rate = get_bits(&gb, 13); +skip_bits(&gb, 3); +fscod = get_bits(&gb, 2); +skip_bits(&gb, 10); +acmod = get_bits(&gb, 3); +lfeon = get_bits(&gb, 1); + +hdr->sample_rate = ff_ac3_sample_rate_tab[fscod]; + +hdr->channels = ff_ac3_channels_tab[acmod] + lfeon; + +hdr->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; +if (lfeon) +hdr->channel_layout |= AV_CH_LOW_FREQUENCY; + +hdr->bit_rate = data_rate*1000; + +return 0; +} + int av_ac3_parse_header(const uint8_t *buf, size_t size, uint8_t *bitstream_id, uint16_t *frame_size) { @@ -256,6 +298,11 @@ int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const uint8_t *buf, return AVERROR(ENOSYS); } +int avpriv_eac3_parse_dec3(AC3HeaderInfo **phdr, const uint8_t *buf, size_t size) +{ +return AVERROR(ENOSYS); +} + int av_ac3_parse_header(const uint8_t *buf, size_t size, uint8_t *bitstream_id, uint16_t *frame_size) { diff --git a/libavcodec/ac3_parser_internal.h b/libavcodec/ac3_parser_internal.h index 3648802a73..0388a5bb5e 100644 --- a/libavcodec/ac3_parser_internal.h +++ b/libavcodec/ac3_parser_internal.h @@ -38,5 +38,9 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr); int avpriv_ac3_parse_header(AC3HeaderInfo **hdr, const uint8_t *buf, size_t size); +/* + * Parse 'dec3' EC3SpecificBox + */ +int avpriv_eac3_parse_dec3(AC3HeaderInfo **phdr, const uint8_t *buf, size_t size); #endif /* AVCODEC_AC3_PARSER_INTERNAL_H */ -- 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".
[FFmpeg-devel] [PATCH 1/2] libavcodec/adts_header: add frame_length field and avpriv function to parse AAC ADTS header
These will be used by HLS demuxer for SAMPLE-AES decryption. Signed-off-by: Nachiket Tarate --- libavcodec/adts_header.c | 18 ++ libavcodec/adts_header.h | 4 2 files changed, 22 insertions(+) diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c index 0889820f8a..006455b110 100644 --- a/libavcodec/adts_header.c +++ b/libavcodec/adts_header.c @@ -3,6 +3,7 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2009 Alex Converse + * Copyright (c) 2020 Nachiket Tarate * * This file is part of FFmpeg. * @@ -66,6 +67,23 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) hdr->sample_rate= avpriv_mpeg4audio_sample_rates[sr]; hdr->samples= (rdb + 1) * 1024; hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; +hdr->frame_length = size; return size; } + +int avpriv_adts_header_parse (AACADTSHeaderInfo *hdr, const uint8_t *buf, size_t size) +{ +int ret = 0; +GetBitContext gb; +if (size < AV_AAC_ADTS_HEADER_SIZE) +return AVERROR_INVALIDDATA; +ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); +if (ret < 0) +return ret; +ret = ff_adts_header_parse(&gb, hdr); +if (ret < 0) +return ret; +return 0; +} + diff --git a/libavcodec/adts_header.h b/libavcodec/adts_header.h index f615f6a9f9..d33bd61818 100644 --- a/libavcodec/adts_header.h +++ b/libavcodec/adts_header.h @@ -2,6 +2,7 @@ * AAC ADTS header decoding prototypes and structures * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2020 Nachiket Tarate * * This file is part of FFmpeg. * @@ -34,6 +35,7 @@ typedef struct AACADTSHeaderInfo { uint8_t sampling_index; uint8_t chan_config; uint8_t num_aac_frames; +uint32_t frame_length; } AACADTSHeaderInfo; /** @@ -47,4 +49,6 @@ typedef struct AACADTSHeaderInfo { */ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); +int avpriv_adts_header_parse (AACADTSHeaderInfo *hdr, const uint8_t *buf, size_t size); + #endif /* AVCODEC_ADTS_HEADER_H */ -- 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".