+++ /dev/null
-diff --git a/libavutil/log.c b/libavutil/log.c
-index 5948e50467..528eaa728c 100644
---- a/libavutil/log.c
-+++ b/libavutil/log.c
-@@ -53,7 +53,7 @@ static AVMutex mutex = AV_MUTEX_INITIALIZER;
- #define BACKTRACE_LOGLEVEL AV_LOG_ERROR
- #endif
-
--static int av_log_level = AV_LOG_INFO;
-+static int av_log_level = AV_LOG_ERROR; // NOT WORKING for libs
- static int flags;
-
- #define NB_LEVELS 8
-@@ -408,10 +408,6 @@ static void (*av_log_callback)(void*, int, const char*, va_list) =
-
- void av_log(void* avcl, int level, const char *fmt, ...)
- {
-- va_list vl;
-- va_start(vl, fmt);
-- av_vlog(avcl, level, fmt, vl);
-- va_end(vl);
- }
-
- void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...)
+++ /dev/null
---- a/libavformat/mpegts.c
-+++ b/libavformat/mpegts.c
-@@ -1041,10 +1041,12 @@
- pes->buffer = NULL;
- reset_pes_packet_state(pes);
-
-+ /*
- sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
- if (!sd)
- return AVERROR(ENOMEM);
- *sd = pes->stream_id;
-+ */
-
- return 0;
- }
+++ /dev/null
---- a/configure
-+++ b/configure
-@@ -3615,10 +3615,8 @@
- # protocols
- async_protocol_deps="threads"
- bluray_protocol_deps="libbluray"
--ffrtmpcrypt_protocol_conflict="librtmp_protocol"
- ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl mbedtls"
- ffrtmpcrypt_protocol_select="tcp_protocol"
--ffrtmphttp_protocol_conflict="librtmp_protocol"
- ffrtmphttp_protocol_select="http_protocol"
- ftp_protocol_select="tcp_protocol"
- gopher_protocol_select="tcp_protocol"
-@@ -3632,20 +3630,18 @@
- icecast_protocol_select="http_protocol"
- mmsh_protocol_select="http_protocol"
- mmst_protocol_select="network"
--rtmp_protocol_conflict="librtmp_protocol"
--rtmp_protocol_select="tcp_protocol"
--rtmp_protocol_suggest="zlib"
--rtmpe_protocol_select="ffrtmpcrypt_protocol"
--rtmpe_protocol_suggest="zlib"
--rtmps_protocol_conflict="librtmp_protocol"
--rtmps_protocol_select="tls_protocol"
--rtmps_protocol_suggest="zlib"
--rtmpt_protocol_select="ffrtmphttp_protocol"
--rtmpt_protocol_suggest="zlib"
--rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
--rtmpte_protocol_suggest="zlib"
--rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
--rtmpts_protocol_suggest="zlib"
-+ffrtmp_protocol_select="tcp_protocol"
-+ffrtmp_protocol_suggest="zlib"
-+ffrtmpe_protocol_select="ffrtmpcrypt_protocol"
-+ffrtmpe_protocol_suggest="zlib"
-+ffrtmps_protocol_select="tls_protocol"
-+ffrtmps_protocol_suggest="zlib"
-+ffrtmpt_protocol_select="ffrtmphttp_protocol"
-+ffrtmpt_protocol_suggest="zlib"
-+ffrtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
-+ffrtmpte_protocol_suggest="zlib"
-+ffrtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
-+ffrtmpts_protocol_suggest="zlib"
- rtp_protocol_select="udp_protocol"
- schannel_conflict="openssl gnutls libtls mbedtls"
- sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags"
---- a/libavformat/Makefile
-+++ b/libavformat/Makefile
-@@ -676,12 +676,12 @@
- OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf_tags.o
- OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
- OBJS-$(CONFIG_PROMPEG_PROTOCOL) += prompeg.o
--OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPTE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPTS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPT_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPTE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPTS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
- OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o ip.o
- OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o
- OBJS-$(CONFIG_SRTP_PROTOCOL) += srtpproto.o srtp.o
---- a/libavformat/protocols.c
-+++ b/libavformat/protocols.c
-@@ -48,12 +48,12 @@
- extern const URLProtocol ff_md5_protocol;
- extern const URLProtocol ff_pipe_protocol;
- extern const URLProtocol ff_prompeg_protocol;
--extern const URLProtocol ff_rtmp_protocol;
--extern const URLProtocol ff_rtmpe_protocol;
--extern const URLProtocol ff_rtmps_protocol;
--extern const URLProtocol ff_rtmpt_protocol;
--extern const URLProtocol ff_rtmpte_protocol;
--extern const URLProtocol ff_rtmpts_protocol;
-+extern const URLProtocol ff_ffrtmp_protocol;
-+extern const URLProtocol ff_ffrtmpe_protocol;
-+extern const URLProtocol ff_ffrtmps_protocol;
-+extern const URLProtocol ff_ffrtmpt_protocol;
-+extern const URLProtocol ff_ffrtmpte_protocol;
-+extern const URLProtocol ff_ffrtmpts_protocol;
- extern const URLProtocol ff_rtp_protocol;
- extern const URLProtocol ff_sctp_protocol;
- extern const URLProtocol ff_srtp_protocol;
---- a/libavformat/rtmpproto.c
-+++ b/libavformat/rtmpproto.c
-@@ -2627,7 +2627,7 @@
- static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)
- {
- RTMPContext *rt = s->priv_data;
-- char proto[8], hostname[256], path[1024], auth[100], *fname;
-+ char *proto, tmpProto[10], hostname[256], path[1024], auth[100], *fname;
- char *old_app, *qmark, *n, fname_buffer[1024];
- uint8_t buf[2048];
- int port;
-@@ -2638,7 +2638,9 @@
-
- rt->is_input = !(flags & AVIO_FLAG_WRITE);
-
-- av_url_split(proto, sizeof(proto), auth, sizeof(auth),
-+ memset(tmpProto, 0, sizeof(tmpProto));
-+ proto = &tmpProto[2];
-+ av_url_split(tmpProto, sizeof(tmpProto), auth, sizeof(auth),
- hostname, sizeof(hostname), &port,
- path, sizeof(path), s->filename);
-
-@@ -3185,9 +3187,9 @@
- #define RTMP_PROTOCOL(flavor, uppercase) \
- RTMP_PROTOCOL_3(flavor, CONFIG_ ## uppercase ## _PROTOCOL)
-
--RTMP_PROTOCOL(rtmp, RTMP)
--RTMP_PROTOCOL(rtmpe, RTMPE)
--RTMP_PROTOCOL(rtmps, RTMPS)
--RTMP_PROTOCOL(rtmpt, RTMPT)
--RTMP_PROTOCOL(rtmpte, RTMPTE)
--RTMP_PROTOCOL(rtmpts, RTMPTS)
-+RTMP_PROTOCOL(ffrtmp, FFRTMP)
-+RTMP_PROTOCOL(ffrtmpe, FFRTMPE)
-+RTMP_PROTOCOL(ffrtmps, FFRTMPS)
-+RTMP_PROTOCOL(ffrtmpt, FFRTMPT)
-+RTMP_PROTOCOL(ffrtmpte, FFRTMPTE)
-+RTMP_PROTOCOL(ffrtmpts, FFRTMPTS)
+++ /dev/null
---- a/libavformat/hls.c
-+++ b/libavformat/hls.c
-@@ -226,6 +226,8 @@
- int http_persistent;
- int http_multiple;
- int http_seekable;
-+ char *key_uri_replace_old;
-+ char *key_uri_replace_new;
- int seg_max_retry;
- AVIOContext *playlist_pb;
- HLSCryptoContext crypto_ctx;
-@@ -1295,8 +1297,16 @@
-
- if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) {
- if (strcmp(seg->key, pls->key_url)) {
-+ char *key_url = NULL;
- AVIOContext *pb = NULL;
-- if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) {
-+ if (NULL != c->key_uri_replace_old && \
-+ NULL != c-> key_uri_replace_new && \
-+ '\0' != c->key_uri_replace_old[0]) {
-+ key_url = av_strireplace(seg->key, c->key_uri_replace_old, c->key_uri_replace_new);
-+ } else {
-+ key_url = seg->key;
-+ }
-+ if (open_url(pls->parent, &pb, key_url, &c->avio_opts, opts, NULL) == 0) {
- ret = avio_read(pb, pls->key, sizeof(pls->key));
- if (ret != sizeof(pls->key)) {
- av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s\n",
-@@ -1308,6 +1318,8 @@
- seg->key);
- }
- av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
-+ if (key_url != seg->key)
-+ av_free(key_url);
- }
- }
-
-@@ -2579,6 +2591,8 @@
- OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
- {"seg_max_retry", "Maximum number of times to reload a segment on error.",
- OFFSET(seg_max_retry), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
-+ { "key_uri_old", "allow to replace part of AES key uri - old", OFFSET(key_uri_replace_old), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
-+ { "key_uri_new", "allow to replace part of AES key uri - new", OFFSET(key_uri_replace_new), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
- {NULL}
- };
-
+++ /dev/null
---- a/configure
-+++ b/configure
-@@ -6132,17 +6132,10 @@
-
- # Check toolchain ISA level
- if enabled mips64; then
-- enabled mips64r6 && check_inline_asm mips64r6 '"dlsa $0, $0, $0, 1"' &&
-- disable mips64r2
--
- enabled mips64r2 && check_inline_asm mips64r2 '"dext $0, $0, 0, 1"'
-
- disable mips32r6 && disable mips32r5 && disable mips32r2
- else
-- enabled mips32r6 && check_inline_asm mips32r6 '"aui $0, $0, 0"' &&
-- disable mips32r5 && disable mips32r2
--
-- enabled mips32r5 && check_inline_asm mips32r5 '"eretnc"'
- enabled mips32r2 && check_inline_asm mips32r2 '"ext $0, $0, 0, 1"'
-
- disable mips64r6 && disable mips64r5 && disable mips64r2
+++ /dev/null
---- a/libavcodec/aacdec_template.c
-+++ b/libavcodec/aacdec_template.c
-@@ -2520,7 +2520,7 @@
- * @param decode 1 if tool is used normally, 0 if tool is used in LTP.
- * @param coef spectral coefficients
- */
--static void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
-+static __attribute__((optimize(0))) void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
- IndividualChannelStream *ics, int decode)
- {
- const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
---- a/libavcodec/aacps.c
-+++ b/libavcodec/aacps.c
-@@ -397,7 +397,7 @@ static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
- par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
- }
-
--static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
-+static void __attribute__((optimize(0))) decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
- {
- LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
- LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
+++ /dev/null
---- a/libavformat/aviobuf.c
-+++ b/libavformat/aviobuf.c
-@@ -34,7 +34,7 @@
- #include "url.h"
- #include <stdarg.h>
-
--#define IO_BUFFER_SIZE 32768
-+#define IO_BUFFER_SIZE 262144
-
- /**
- * Do seeks within this distance ahead of the current buffer by skipping
-@@ -580,16 +580,15 @@
- }
-
- /* make buffer smaller in case it ended up large after probing */
-- if (s->read_packet && ctx->orig_buffer_size &&
-- s->buffer_size > ctx->orig_buffer_size && len >= ctx->orig_buffer_size) {
-+ if (s->read_packet && s->buffer_size > max_buffer_size) {
- if (dst == s->buffer && s->buf_ptr != dst) {
-- int ret = set_buf_size(s, ctx->orig_buffer_size);
-+ int ret = set_buf_size(s, max_buffer_size);
- if (ret < 0)
- av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
-
- s->checksum_ptr = dst = s->buffer;
- }
-- len = ctx->orig_buffer_size;
-+ len = max_buffer_size;
- }
-
- len = read_packet_wrapper(s, dst, len);
+++ /dev/null
---- a/libavformat/hls.c
-+++ b/libavformat/hls.c
-@@ -2298,8 +2298,10 @@
- HLSContext *c = s->priv_data;
- int ret, i, minplaylist = -1;
-
-- recheck_discard_flags(s, c->first_packet);
-- c->first_packet = 0;
-+ if (c->first_packet) {
-+ recheck_discard_flags(s, 1);
-+ c->first_packet = 0;
-+ }
-
- for (i = 0; i < c->n_playlists; i++) {
- struct playlist *pls = c->playlists[i];
+++ /dev/null
---- a/libavformat/mov.c
-+++ b/libavformat/mov.c
-@@ -3966,8 +3966,10 @@
-
- if (ctts_data_old && ctts_index_old < ctts_count_old) {
- curr_ctts = ctts_data_old[ctts_index_old].duration;
-+ /*
- av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
- curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
-+ */
- curr_cts += curr_ctts;
- ctts_sample_old++;
- if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
+++ /dev/null
---- a/libavformat/dashdec.c
-+++ b/libavformat/dashdec.c
-@@ -1400,6 +1400,9 @@
- } else {
- num = pls->first_seq_no + (((c->publish_time - c->time_shift_buffer_depth + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
- }
-+ } else if (c->period_start && c->availability_start_time && pls->fragment_timescale) {
-+ num = pls->first_seq_no + ((( get_current_time_in_sec() - (c->availability_start_time + c->period_start)) * pls->fragment_timescale) - pls->fragment_duration)/ pls->fragment_duration;
-+
- } else {
- num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
- }
+++ /dev/null
---- a/libavformat/rtsp.c
-+++ b/libavformat/rtsp.c
-@@ -2392,6 +2392,8 @@ static int sdp_read_header(AVFormatContext *s)
- int i, err;
- char url[MAX_URL_SIZE];
- AVBPrint bp;
-+ const char *p, *sp="", *sources="", *sp2, *sources2;
-+ char sources_buf[1024];
-
- if (!ff_network_init())
- return AVERROR(EIO);
-@@ -2413,6 +2415,16 @@ static int sdp_read_header(AVFormatContext *s)
- av_bprint_finalize(&bp, NULL);
- if (err) goto fail;
-
-+ /* Search for sources= tag in original URL for rtp protocol only */
-+ if (strncmp(s->url, "rtp://", 6) == 0) {
-+ p = strchr(s->url, '?');
-+ if (p && av_find_info_tag(sources_buf, sizeof(sources_buf), "sources", p)) {
-+ /* av_log(s, AV_LOG_VERBOSE, "sdp_read_header found sources %s\n", sources_buf); */
-+ sp = sources_buf;
-+ sources = "&sources=";
-+ }
-+ }
-+
- /* open each RTP stream */
- for (i = 0; i < rt->nb_rtsp_streams; i++) {
- char namebuf[50];
-@@ -2432,12 +2445,22 @@ static int sdp_read_header(AVFormatContext *s)
- av_dict_free(&opts);
- goto fail;
- }
-+
-+ /* Prepare to add sources to the url to be opened.
-+ Otherwise the join to the source specific muliticast will be missing */
-+ sources2 = sources;
-+ sp2 = sp;
-+ /* ignore sources from original URL, when sources are already set in rtsp_st */
-+ if (rtsp_st->nb_include_source_addrs > 0)
-+ sources2 = sp2 = "";
-+
- ff_url_join(url, sizeof(url), "rtp", NULL,
- namebuf, rtsp_st->sdp_port,
-- "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
-+ "?localport=%d&ttl=%d&connect=%d&write_to_source=%d%s%s",
- rtsp_st->sdp_port, rtsp_st->sdp_ttl,
- rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
-- rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
-+ rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0,
-+ sources2, sp2);
-
- p = strchr(s->url, '?');
- if (p && av_find_info_tag(buf, sizeof(buf), "localaddr", p))
+++ /dev/null
---- a/libavcodec/dxva2.c
-+++ b/libavcodec/dxva2.c
-@@ -777,16 +777,18 @@
- #if CONFIG_D3D11VA
- if (avctx->pix_fmt == AV_PIX_FMT_D3D11)
- return (intptr_t)frame->data[1];
-- if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
-+ if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && surface) {
- D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
- ID3D11VideoDecoderOutputView_GetDesc((ID3D11VideoDecoderOutputView*) surface, &viewDesc);
- return viewDesc.Texture2D.ArraySlice;
- }
- #endif
- #if CONFIG_DXVA2
-- for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
-- if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
-- return i;
-+ if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
-+ for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
-+ if (ctx->dxva2.surface[i] == surface)
-+ return i;
-+ }
- }
- #endif
-
---- a/libavcodec/dxva2_h264.c
-+++ b/libavcodec/dxva2_h264.c
-@@ -507,6 +507,14 @@
-
- if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
- return -1;
-+
-+ // Wait for an I-frame before start decoding. Workaround for ATI UVD and UVD+ GPUs
-+ if (!h->got_first_iframe) {
-+ if (!(ctx_pic->pp.wBitFields & (1 << 15)))
-+ return -1;
-+ h->got_first_iframe = 1;
-+ }
-+
- ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr->f,
- &ctx_pic->pp, sizeof(ctx_pic->pp),
- &ctx_pic->qm, sizeof(ctx_pic->qm),
---- a/libavcodec/h264_slice.c
-+++ b/libavcodec/h264_slice.c
-@@ -978,6 +978,7 @@
-
- h->first_field = 0;
- h->prev_interlaced_frame = 1;
-+ h->got_first_iframe = 0;
-
- init_scan_tables(h);
- ret = ff_h264_alloc_tables(h);
---- a/libavcodec/h264dec.c
-+++ b/libavcodec/h264dec.c
-@@ -456,6 +456,7 @@
-
- h->next_outputed_poc = INT_MIN;
- h->prev_interlaced_frame = 1;
-+ h->got_first_iframe = 0;
- idr(h);
-
- h->poc.prev_frame_num = -1;
---- a/libavcodec/h264dec.h
-+++ b/libavcodec/h264dec.h
-@@ -533,6 +533,8 @@
- * slices) anymore */
- int setup_finished;
-
-+ int got_first_iframe;
-+
- int cur_chroma_format_idc;
- int cur_bit_depth_luma;
- int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
---- a/libavcodec/vaapi_h264.c
-+++ b/libavcodec/vaapi_h264.c
-@@ -314,6 +314,11 @@
- H264SliceContext *sl = &h->slice_ctx[0];
- int ret;
-
-+ if (pic->nb_slices == 0) {
-+ ret = AVERROR_INVALIDDATA;
-+ goto finish;
-+ }
-+
- ret = ff_vaapi_decode_issue(avctx, pic);
- if (ret < 0)
- goto finish;
---- a/libavformat/bintext.c
-+++ b/libavformat/bintext.c
-@@ -149,7 +149,7 @@
- return AVPROBE_SCORE_EXTENSION + 1;
-
- predict_width(&par, p->buf_size, got_width);
-- if (par.width < 8)
-+ if (par.width <= 0)
- return 0;
- calculate_height(&par, p->buf_size);
- if (par.height <= 0)
-@@ -189,8 +189,6 @@
- next_tag_read(s, &bin->fsize);
- if (!bin->width) {
- predict_width(st->codecpar, bin->fsize, got_width);
-- if (st->codecpar->width < 8)
-- return AVERROR_INVALIDDATA;
- calculate_height(st->codecpar, bin->fsize);
- }
- avio_seek(pb, 0, SEEK_SET);
+++ /dev/null
---- a/libavformat/avformat.h
-+++ b/libavformat/avformat.h
-@@ -1030,6 +1030,10 @@
- int64_t av_stream_get_end_pts(const AVStream *st);
- #endif
-
-+// Chromium: We use the internal field first_dts vvv
-+int64_t av_stream_get_first_dts(const AVStream *st);
-+// Chromium: We use the internal field first_dts ^^^
-+
- #define AV_PROGRAM_RUNNING 1
-
- /**
---- a/libavformat/utils.c
-+++ b/libavformat/utils.c
-@@ -100,6 +100,13 @@
- return pkt->size > orig_size ? pkt->size - orig_size : ret;
- }
-
-+// Chromium: We use the internal field first_dts vvv
-+int64_t av_stream_get_first_dts(const AVStream *st)
-+{
-+ return cffstream(st)->first_dts;
-+}
-+// Chromium: We use the internal field first_dts ^^^
-+
- int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
- {
- #if FF_API_INIT_PACKET
+++ /dev/null
---- a/libavformat/avio.c
-+++ b/libavformat/avio.c
-@@ -171,12 +171,12 @@
- (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value)));
- av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
- (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value)));
--
-+/*
- if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) {
- av_log(uc, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", uc->prot->name, uc->protocol_whitelist);
- return AVERROR(EINVAL);
- }
--
-+*/
- if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) {
- av_log(uc, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", uc->prot->name, uc->protocol_blacklist);
- return AVERROR(EINVAL);
+++ /dev/null
---- a/doc/demuxers.texi
-+++ b/doc/demuxers.texi
-@@ -281,7 +281,11 @@
- @table @option
-
- @item cenc_decryption_key
--16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
-+Default 16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
-+
-+ at item cenc_decryption_keys
-+Dictionary of 16-byte key ID => 16-byte key, both in hex, to decrypt files encrypted using ISO Common Encryption
-+(CENC/AES-128 CTR; ISO/IEC 23001-7).
-
- @end table
-
-@@ -769,7 +773,11 @@
- specify.
-
- @item decryption_key
--16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
-+Default 16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
-+
-+ at item decryption_keys
-+Dictionary of 16-byte key ID => 16-byte key, both in hex, to decrypt files encrypted using ISO Common Encryption
-+(CENC/AES-128 CTR; ISO/IEC 23001-7).
-
- @item max_stts_delta
- Very high sample deltas written in a trak's stts box may occasionally be intended but usually they are written in
---- a/libavformat/dashdec.c
-+++ b/libavformat/dashdec.c
-@@ -153,6 +153,7 @@
- AVDictionary *avio_opts;
- int max_url_size;
- char *cenc_decryption_key;
-+ char *cenc_decryption_keys;
-
- /* Flags for init section*/
- int is_init_section_common_video;
-@@ -1906,6 +1907,8 @@
-
- if (c->cenc_decryption_key)
- av_dict_set(&in_fmt_opts, "decryption_key", c->cenc_decryption_key, 0);
-+ if (c->cenc_decryption_keys)
-+ av_dict_set(&in_fmt_opts, "decryption_keys", c->cenc_decryption_keys, 0);
-
- // provide additional information from mpd if available
- ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts); //pls->init_section->url
-@@ -2347,7 +2350,8 @@
- OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
- {.str = "aac,m4a,m4s,m4v,mov,mp4,webm,ts"},
- INT_MIN, INT_MAX, FLAGS},
-- { "cenc_decryption_key", "Media decryption key (hex)", OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
-+ { "cenc_decryption_key", "Media default decryption key (hex)", OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
-+ { "cenc_decryption_keys", "Media decryption keys by KID (hex)", OFFSET(cenc_decryption_keys), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
- {NULL}
- };
-
---- a/libavformat/isom.h
-+++ b/libavformat/isom.h
-@@ -312,8 +312,8 @@
- void *audible_iv;
- int audible_iv_size;
- struct AVAES *aes_decrypt;
-- uint8_t *decryption_key;
-- int decryption_key_len;
-+ uint8_t *decryption_default_key;
-+ int decryption_default_key_len;
- int enable_drefs;
- int32_t movie_display_matrix[3][3]; ///< display matrix from mvhd
- int have_read_mfra_size;
-@@ -328,6 +328,7 @@
- } *avif_info;
- int avif_info_size;
- int interleaved_read;
-+ AVDictionary* decryption_keys;
- } MOVContext;
-
- int ff_mp4_read_descr_len(AVIOContext *pb);
---- a/libavformat/mov.c
-+++ b/libavformat/mov.c
-@@ -7130,19 +7130,62 @@
- return 0;
- }
-
-+static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
-+ AVDictionaryEntry *key_entry_hex;
-+ char kid_hex[16*2+1];
-+
-+ if (c->decryption_default_key && c->decryption_default_key_len != len) {
-+ av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
-+ return -1;
-+ }
-+
-+ if (!c->decryption_keys) {
-+ av_assert0(c->decryption_default_key);
-+ memcpy(out, c->decryption_default_key, len);
-+ return 0;
-+ }
-+
-+ if (sample->key_id_size != 16) {
-+ av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
-+ return -1;
-+ }
-+
-+ ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
-+ key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
-+ if (!key_entry_hex) {
-+ if (!c->decryption_default_key) {
-+ av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
-+ return -1;
-+ }
-+ memcpy(out, c->decryption_default_key, len);
-+ return 0;
-+ }
-+ if (strlen(key_entry_hex->value) != len*2) {
-+ return -1;
-+ }
-+ ff_hex_to_data(out, key_entry_hex->value);
-+ return 0;
-+}
-+
- static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
- {
- int i, ret;
- int bytes_of_protected_data;
-+ uint8_t decryption_key[AES_CTR_KEY_SIZE];
-
- if (!sc->cenc.aes_ctr) {
-+ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
-+ if (ret < 0) {
-+ return ret;
-+ }
-+
- /* 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);
-+ ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
- if (ret < 0) {
- return ret;
- }
-@@ -7188,15 +7231,21 @@
- int i, ret;
- int num_of_encrypted_blocks;
- uint8_t iv[16];
-+ uint8_t decryption_key[16];
-
- if (!sc->cenc.aes_ctx) {
-+ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
-+ if (ret < 0) {
-+ return ret;
-+ }
-+
- /* 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);
-+ ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
- if (ret < 0) {
- return ret;
- }
-@@ -7247,15 +7296,21 @@
- {
- int i, ret, rem_bytes;
- uint8_t *data;
-+ uint8_t decryption_key[AES_CTR_KEY_SIZE];
-
- if (!sc->cenc.aes_ctr) {
-+ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
-+ if (ret < 0) {
-+ return ret;
-+ }
-+
- /* 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);
-+ ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
- if (ret < 0) {
- return ret;
- }
-@@ -7313,15 +7368,21 @@
- int i, ret, rem_bytes;
- uint8_t iv[16];
- uint8_t *data;
-+ uint8_t decryption_key[16];
-
- if (!sc->cenc.aes_ctx) {
-+ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
-+ if (ret < 0) {
-+ return ret;
-+ }
-+
- /* 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);
-+ ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
- if (ret < 0) {
- return ret;
- }
-@@ -7464,7 +7525,7 @@
- return AVERROR_INVALIDDATA;
- }
-
-- if (mov->decryption_key) {
-+ if (mov->decryption_keys || mov->decryption_default_key) {
- return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
- } else {
- size_t size;
-@@ -8613,12 +8674,6 @@
- MOVAtom atom = { AV_RL32("root") };
- int i;
-
-- if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
-- av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
-- mov->decryption_key_len, AES_CTR_KEY_SIZE);
-- return AVERROR(EINVAL);
-- }
--
- mov->fc = s;
- mov->trak_index = -1;
- /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
-@@ -9317,7 +9372,8 @@
- "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
- AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
- .flags = AV_OPT_FLAG_DECODING_PARAM },
-- { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
-+ { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
-+ { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
- { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
- {.i64 = 0}, 0, 1, FLAGS },
- { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM },
---- a/tests/fate/mov.mak
-+++ b/tests/fate/mov.mak
-@@ -8,6 +8,9 @@
- fate-mov-3elist-encrypted \
- fate-mov-frag-encrypted \
- fate-mov-tenc-only-encrypted \
-+ fate-mov-3elist-encrypted-kid \
-+ fate-mov-frag-encrypted-kid \
-+ fate-mov-tenc-only-encrypted-kid \
- fate-mov-invalid-elst-entry-count \
- fate-mov-gpmf-remux \
- fate-mov-440hz-10ms \
-@@ -57,6 +60,15 @@ fate-mov-frag-encrypted: CMD = framemd5 -decryption_key 123456789012345678901234
- # Full-sample encryption and constant IV using only tenc atom (no senc/saio/saiz).
- fate-mov-tenc-only-encrypted: CMD = framemd5 -decryption_key 12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-tenc-only-encrypted.mp4
-
-+# Edit list with encryption, using the decryption_keys option.
-+fate-mov-3elist-encrypted-kid: CMD = framemd5 -decryption_keys 12345678901234567890123456789012=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-3elist-encrypted.mov
-+
-+# Fragmented encryption with senc boxes in movie fragments, using the decryption_keys option.
-+fate-mov-frag-encrypted-kid: CMD = framemd5 -decryption_keys abba271e8bcf552bbd2e86a434a9a5d9=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-frag-encrypted.mp4
-+
-+# Full-sample encryption and constant IV using only tenc atom (no senc/saio/saiz), using the decryption_keys option.
-+fate-mov-tenc-only-encrypted-kid: CMD = framemd5 -decryption_keys abba271e8bcf552bbd2e86a434a9a5d9=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-tenc-only-encrypted.mp4
-+
- # Makes sure that the CTTS is also modified when we fix avindex in mov.c while parsing edit lists.
- fate-mov-elist-starts-ctts-2ndsample: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-elist-starts-ctts-2ndsample.mov
-
---- /dev/null
-+++ b/tests/ref/fate/mov-3elist-encrypted-kid
-@@ -0,0 +1,57 @@
-+#format: frame checksums
-+#version: 2
-+#hash: MD5
-+#tb 0: 1/24
-+#media_type 0: video
-+#codec_id 0: rawvideo
-+#dimensions 0: 640x480
-+#sar 0: 0/1
-+#stream#, dts, pts, duration, size, hash
-+0, 0, 0, 1, 460800, 80fbbdec589e15e6c493b44d243f92a9
-+0, 1, 1, 1, 460800, f4b23293bb2ecf69cc3570853d8c56a1
-+0, 2, 2, 1, 460800, 0c03ce2c1c6ec405d7455465ecd559a3
-+0, 3, 3, 1, 460800, 7921791695537fba2c3c123da4834cb9
-+0, 4, 4, 1, 460800, 30c8e2903a561b84d4cbaf95c668d236
-+0, 5, 5, 1, 460800, 7ff42e998217c17592ddf6b584f26cef
-+0, 6, 6, 1, 460800, 5e402c48bf097db2d31b82bb4194a382
-+0, 7, 7, 1, 460800, 824c49e92c8ae6d99a0207b514dd756c
-+0, 8, 8, 1, 460800, 24f189216a1d9cf2313b2d6dbe3dbdd3
-+0, 9, 9, 1, 460800, 519179a8e74275d26b183374637e003f
-+0, 10, 10, 1, 460800, f18331ddcef0adf5b069bfa98baf8db4
-+0, 11, 11, 1, 460800, 081f61688690d47dbdddd5384e5d5a70
-+0, 12, 12, 1, 460800, 90dbf019b9035433371a8df41a9268b7
-+0, 13, 13, 1, 460800, bb5adfb9c66732898b34186eca1667ba
-+0, 14, 14, 1, 460800, cc08cfd64f37783ecddaf143f6ad78bc
-+0, 15, 15, 1, 460800, b8ae21d024fe4df903d56f4521993c72
-+0, 16, 16, 1, 460800, b45a99907f045dcadf0a2befc11555e3
-+0, 17, 17, 1, 460800, 603ba935845e65ab6cccbbec88bbf60d
-+0, 18, 18, 1, 460800, df80c8d3e6a77258a306903f17995a18
-+0, 19, 19, 1, 460800, 4b7e90c0a5fd0e0cd958d47f0afac636
-+0, 20, 20, 1, 460800, 9feb6e36182f1745be6387edea240eb6
-+0, 21, 21, 1, 460800, 86e6de4bd0a5ff7558f4cf6c1ec3930d
-+0, 22, 22, 1, 460800, 726b69df77edbe7b503d4698656d1320
-+0, 23, 23, 1, 460800, d282fb7a953ac205b0a43d00c2d60a33
-+0, 24, 24, 1, 460800, eece3daa70cc20208dd75d91ac84c8fd
-+0, 25, 25, 1, 460800, c86d23e73bcce351fc315fb1f13348da
-+0, 26, 26, 1, 460800, 93497b4f7c5ad9d61212239b7c9d2770
-+0, 27, 27, 1, 460800, eb217d2c12de67903835a8c58f620488
-+0, 28, 28, 1, 460800, d966480867bb54c8cd044f18388ed486
-+0, 29, 29, 1, 460800, 3ea6207942b3181fdd8e8aa6cae1062a
-+0, 30, 30, 1, 460800, 2620df54aca086ec0fb9527c6e6f5135
-+0, 31, 31, 1, 460800, 43bb7320f0bb583188dc965ddbfade90
-+0, 32, 32, 1, 460800, 0cddaa04645f804e02f65b0836412113
-+0, 33, 33, 1, 460800, 83b2dc95807289d7f4a4632bf18c2e97
-+0, 34, 34, 1, 460800, 98134d0e41e6dd12827049ccf33b4669
-+0, 35, 35, 1, 460800, 56f55631731fa39c7acbab0afeb2eb1b
-+0, 36, 36, 1, 460800, 379c1105be09d836a515dc909455ddf4
-+0, 37, 37, 1, 460800, 1df87c47e9d98731faf1c3885b77e5da
-+0, 38, 38, 1, 460800, 9a8734bcbfdb4d97e530683b8b556a26
-+0, 39, 39, 1, 460800, c7a7990d0cddc5adfbe27da7a42e025e
-+0, 40, 40, 1, 460800, 0c81e46011e03be410feaf056207fd55
-+0, 41, 41, 1, 460800, ca76e4e63016ff29d8aeeb9cb053bb6c
-+0, 42, 42, 1, 460800, cebfbe299c17c1f8fc1e6b189555c3c2
-+0, 43, 43, 1, 460800, 4f002c5feca5e75f07089e0df47507dd
-+0, 44, 44, 1, 460800, c5fd83fc4a745abee9b3d9a6eec9dd3e
-+0, 45, 45, 1, 460800, 57d9bad9b45aa2746de5d8bdc2c24969
-+0, 46, 46, 1, 460800, 9831673ad7dec167af4a959f64258949
-+0, 47, 47, 1, 460800, 77a1cb208f70f51bcb01e28d8cba73b4
---- /dev/null
-+++ b/tests/ref/fate/mov-frag-encrypted-kid
-@@ -0,0 +1,57 @@
-+#format: frame checksums
-+#version: 2
-+#hash: MD5
-+#tb 0: 1/24
-+#media_type 0: video
-+#codec_id 0: rawvideo
-+#dimensions 0: 120x52
-+#sar 0: 544/545
-+#stream#, dts, pts, duration, size, hash
-+0, 0, 0, 1, 9360, 920bdc277a6a31c1daed9aca44b10caf
-+0, 1, 1, 1, 9360, f1c0b61fef593de57cb97be7fa846569
-+0, 2, 2, 1, 9360, 6ef32d9d4398355aebf6d3fb11d51d3f
-+0, 3, 3, 1, 9360, d38fd3ef1e5a92fc109b8dd9eb6dadeb
-+0, 4, 4, 1, 9360, 54cc0c8a25d2f14f32663837d5e646f1
-+0, 5, 5, 1, 9360, b4b6829726dc3decb8b80ba0c35bcf30
-+0, 6, 6, 1, 9360, fca3f941e60a2f0a4ce30d5e0efbec3c
-+0, 7, 7, 1, 9360, cda6e26b6c1039ff3d229b262c9210c3
-+0, 8, 8, 1, 9360, f0d69255e3a27a8b4ae8a4b7b210929d
-+0, 9, 9, 1, 9360, 12cb23dd4e32af9c3b35f943714e3fdd
-+0, 10, 10, 1, 9360, 082aaf3216124ddcecb422fe5c832e82
-+0, 11, 11, 1, 9360, ff37bb8cd6bd0412a3b3cb45db54afc9
-+0, 12, 12, 1, 9360, dfb9085441575732844b6c2f05d5f542
-+0, 13, 13, 1, 9360, 0017100feaaa9fc7eacd2447d50d7542
-+0, 14, 14, 1, 9360, 4e2f1b8c4e04c59934c2f58541e62613
-+0, 15, 15, 1, 9360, 27a44dfea7cd2d30e488194c34ab473c
-+0, 16, 16, 1, 9360, fc7b56bd95e990a33cf575d1ef820902
-+0, 17, 17, 1, 9360, fa2d1609e69714dffc410e65f3c8b755
-+0, 18, 18, 1, 9360, 705d7429f447cb13febe202d567795f2
-+0, 19, 19, 1, 9360, 234802ce86e868faaf2cd40a286846ea
-+0, 20, 20, 1, 9360, 2f0354b40d211d0a4ade4568bea4f85e
-+0, 21, 21, 1, 9360, e96af3b6c0cc931463ca77d6be0f1148
-+0, 22, 22, 1, 9360, 04a904d798361959971361401879c7e4
-+0, 23, 23, 1, 9360, 2f119642340df6d25362b5590ded46b7
-+0, 24, 24, 1, 9360, 5993fca2e60050706f857ac76e48f386
-+0, 25, 25, 1, 9360, 2ff3b5775fed3d527bfbbeea786787fe
-+0, 26, 26, 1, 9360, 42024dbe23d3fb5b0d8987ae1ce390a8
-+0, 27, 27, 1, 9360, d804204f0bd9db5f6a758e2c934d9e38
-+0, 28, 28, 1, 9360, e322712e6e34c58ec1a2ab5e2c1e3bfe
-+0, 29, 29, 1, 9360, 3975bd1a5f6a6b6260276777f9de611e
-+0, 30, 30, 1, 9360, 4388f0412efc6310706a7cdedc859ea9
-+0, 31, 31, 1, 9360, b4b9a11b0b86635267345a569640e8d4
-+0, 32, 32, 1, 9360, 31879c7b8d6b67a4209ffde786bb8cb4
-+0, 33, 33, 1, 9360, 4b6dc02d7c889fe4abd4e013b25f585a
-+0, 34, 34, 1, 9360, dc73aae82bd39a1220d1106c8d3e8252
-+0, 35, 35, 1, 9360, 54c7dfbd49f312806f6c1a89f7c2c36f
-+0, 36, 36, 1, 9360, 150abc64f8994d444a521ea90570443c
-+0, 37, 37, 1, 9360, d277cdc7dcadbe0016f2e950459e7ebf
-+0, 38, 38, 1, 9360, 2196bf338ead90ea54687b85c73c8229
-+0, 39, 39, 1, 9360, 53ce5da5365abc0bd3217dd98e7c465d
-+0, 40, 40, 1, 9360, 34ee9832aea55c0c4e6f4381c413c10e
-+0, 41, 41, 1, 9360, 1769c7b5849e4681119067a06ac29a4f
-+0, 42, 42, 1, 9360, 71f53df739ef283a5184c91ef4b158e8
-+0, 43, 43, 1, 9360, d2d394739e9a59c06f0354c16843cb63
-+0, 44, 44, 1, 9360, d8e458e92ae29344505a24a3059fc584
-+0, 45, 45, 1, 9360, 0f1b11a09911851b798df2ef76253a7f
-+0, 46, 46, 1, 9360, 5c4a9f22baecf4e749c0d5c65a4f1007
-+0, 47, 47, 1, 9360, 3e2b7e7262fdca08d9d1ef6070125c4b
---- /dev/null
-+++ b/tests/ref/fate/mov-tenc-only-encrypted-kid
-@@ -0,0 +1,57 @@
-+#format: frame checksums
-+#version: 2
-+#hash: MD5
-+#tb 0: 1/24
-+#media_type 0: video
-+#codec_id 0: rawvideo
-+#dimensions 0: 1024x436
-+#sar 0: 1/1
-+#stream#, dts, pts, duration, size, hash
-+0, 0, 0, 1, 669696, f48f296a85eda5ba069dc851a3228bef
-+0, 1, 1, 1, 669696, a50c5f69bfa3387d49b5bdf738e6529c
-+0, 2, 2, 1, 669696, 05061299003760f6a4795b408f72aa31
-+0, 3, 3, 1, 669696, 2572119f0b0cdd83f8a7e06252cecd3b
-+0, 4, 4, 1, 669696, 29fe6a6bdb4a69018e318886a297f07e
-+0, 5, 5, 1, 669696, e8233c7fbaecfbff965c7dfdd3982b1b
-+0, 6, 6, 1, 669696, d9259df9880ff5d4a4b38282e67f407b
-+0, 7, 7, 1, 669696, 3e8d795195038993503ea9ab6984c915
-+0, 8, 8, 1, 669696, bc4e2d253b715a34f85aae1b080e3460
-+0, 9, 9, 1, 669696, 09aba8b3a96f53f9268e7420a10bfab6
-+0, 10, 10, 1, 669696, 179447977dd580da8b35fb5310a809ca
-+0, 11, 11, 1, 669696, 7a0eea9d54577990345f5705ab9882be
-+0, 12, 12, 1, 669696, 5bb96eb76f461825740e5938456df759
-+0, 13, 13, 1, 669696, bd4ac4a760ead774b9422a27dc071964
-+0, 14, 14, 1, 669696, 1cc05f760a9b751fc89e77f2bcc97259
-+0, 15, 15, 1, 669696, 825d0dee6f0174ba7102892c7de30b4d
-+0, 16, 16, 1, 669696, d26a2ef5267f6bb03c4e1d8514eee0df
-+0, 17, 17, 1, 669696, c916ffdeadca76596a8f7fd47914b5ef
-+0, 18, 18, 1, 669696, 6e085acfa7fee0658ea0ae6188274c17
-+0, 19, 19, 1, 669696, 1e95fa5b3561283f05bf0bd44cb91721
-+0, 20, 20, 1, 669696, 37e3d135aba9dfb8b87e441753115374
-+0, 21, 21, 1, 669696, 9c398310e8564491de624393c16265ce
-+0, 22, 22, 1, 669696, c87209e4d2617bc2ab40a75f455f09da
-+0, 23, 23, 1, 669696, 2679c2f8d1d1af21982e245945c1ee60
-+0, 24, 24, 1, 669696, 6151ab4781f31c5beb66b356ad547122
-+0, 25, 25, 1, 669696, f7ef6293bfb3a6a329061cb6a5ed5a38
-+0, 26, 26, 1, 669696, 2f6e666d14dfc407ca0c0f347b13eb08
-+0, 27, 27, 1, 669696, 3454fa1730d79b1aa8dbbc865dc150f4
-+0, 28, 28, 1, 669696, e93dc683e2453419a0419ab9af0f8f95
-+0, 29, 29, 1, 669696, 031eb3154f7f83cf86d42bee66be9cf7
-+0, 30, 30, 1, 669696, 1205c36723e88811206c68892d3aaed6
-+0, 31, 31, 1, 669696, 7dd7a8a19dcd73b31ddc6a6d0c597a42
-+0, 32, 32, 1, 669696, 7c91115368ea2531262a1197468bc3f4
-+0, 33, 33, 1, 669696, 3cf6d9ba385e0fff76da33299ed5380c
-+0, 34, 34, 1, 669696, 859fc8c3ef049e3c1175a85fb0a90a3d
-+0, 35, 35, 1, 669696, 1d09ce6c7027103d99a4d5799f6e72ab
-+0, 36, 36, 1, 669696, 3dcb8357408ac88abd734128d8f5dd6f
-+0, 37, 37, 1, 669696, 4dafce137a0a5178f6efaec878e64d36
-+0, 38, 38, 1, 669696, 44c478f29a1399ed03275a7357f57d48
-+0, 39, 39, 1, 669696, 6e9edaac7414c0e14591ac3d4d0b1ac4
-+0, 40, 40, 1, 669696, 522e4aaeea0825da27f631a9e690d654
-+0, 41, 41, 1, 669696, 85f2502a718440834c40051d30f8a65e
-+0, 42, 42, 1, 669696, ae8816f7bd4645ef1a17ee6d09b4c8d2
-+0, 43, 43, 1, 669696, 914b006fa92f1eb3e590245749f6810d
-+0, 44, 44, 1, 669696, 9406901542e94c429dff46108782ed69
-+0, 45, 45, 1, 669696, 324c13641c39eef5c476023e358c0391
-+0, 46, 46, 1, 669696, 4058e886e17c22e4eb9da1dd0d6ad891
-+0, 47, 47, 1, 669696, 9edf9cd15eea985b42fd1f5035b1d693
---
--- /dev/null
+diff --git a/libavutil/log.c b/libavutil/log.c
+index 5948e50467..528eaa728c 100644
+--- a/libavutil/log.c
++++ b/libavutil/log.c
+@@ -53,7 +53,7 @@ static AVMutex mutex = AV_MUTEX_INITIALIZER;
+ #define BACKTRACE_LOGLEVEL AV_LOG_ERROR
+ #endif
+
+-static int av_log_level = AV_LOG_INFO;
++static int av_log_level = AV_LOG_ERROR; // NOT WORKING for libs
+ static int flags;
+
+ #define NB_LEVELS 8
+@@ -408,10 +408,6 @@ static void (*av_log_callback)(void*, int, const char*, va_list) =
+
+ void av_log(void* avcl, int level, const char *fmt, ...)
+ {
+- va_list vl;
+- va_start(vl, fmt);
+- av_vlog(avcl, level, fmt, vl);
+- va_end(vl);
+ }
+
+ void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...)
--- /dev/null
+--- a/libavformat/mpegts.c
++++ b/libavformat/mpegts.c
+@@ -1041,10 +1041,12 @@
+ pes->buffer = NULL;
+ reset_pes_packet_state(pes);
+
++ /*
+ sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
+ if (!sd)
+ return AVERROR(ENOMEM);
+ *sd = pes->stream_id;
++ */
+
+ return 0;
+ }
--- /dev/null
+--- a/configure
++++ b/configure
+@@ -3615,10 +3615,8 @@
+ # protocols
+ async_protocol_deps="threads"
+ bluray_protocol_deps="libbluray"
+-ffrtmpcrypt_protocol_conflict="librtmp_protocol"
+ ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl mbedtls"
+ ffrtmpcrypt_protocol_select="tcp_protocol"
+-ffrtmphttp_protocol_conflict="librtmp_protocol"
+ ffrtmphttp_protocol_select="http_protocol"
+ ftp_protocol_select="tcp_protocol"
+ gopher_protocol_select="tcp_protocol"
+@@ -3632,20 +3630,18 @@
+ icecast_protocol_select="http_protocol"
+ mmsh_protocol_select="http_protocol"
+ mmst_protocol_select="network"
+-rtmp_protocol_conflict="librtmp_protocol"
+-rtmp_protocol_select="tcp_protocol"
+-rtmp_protocol_suggest="zlib"
+-rtmpe_protocol_select="ffrtmpcrypt_protocol"
+-rtmpe_protocol_suggest="zlib"
+-rtmps_protocol_conflict="librtmp_protocol"
+-rtmps_protocol_select="tls_protocol"
+-rtmps_protocol_suggest="zlib"
+-rtmpt_protocol_select="ffrtmphttp_protocol"
+-rtmpt_protocol_suggest="zlib"
+-rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
+-rtmpte_protocol_suggest="zlib"
+-rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
+-rtmpts_protocol_suggest="zlib"
++ffrtmp_protocol_select="tcp_protocol"
++ffrtmp_protocol_suggest="zlib"
++ffrtmpe_protocol_select="ffrtmpcrypt_protocol"
++ffrtmpe_protocol_suggest="zlib"
++ffrtmps_protocol_select="tls_protocol"
++ffrtmps_protocol_suggest="zlib"
++ffrtmpt_protocol_select="ffrtmphttp_protocol"
++ffrtmpt_protocol_suggest="zlib"
++ffrtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
++ffrtmpte_protocol_suggest="zlib"
++ffrtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
++ffrtmpts_protocol_suggest="zlib"
+ rtp_protocol_select="udp_protocol"
+ schannel_conflict="openssl gnutls libtls mbedtls"
+ sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags"
+--- a/libavformat/Makefile
++++ b/libavformat/Makefile
+@@ -676,12 +676,12 @@
+ OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf_tags.o
+ OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+ OBJS-$(CONFIG_PROMPEG_PROTOCOL) += prompeg.o
+-OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPT_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+ OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o ip.o
+ OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o
+ OBJS-$(CONFIG_SRTP_PROTOCOL) += srtpproto.o srtp.o
+--- a/libavformat/protocols.c
++++ b/libavformat/protocols.c
+@@ -48,12 +48,12 @@
+ extern const URLProtocol ff_md5_protocol;
+ extern const URLProtocol ff_pipe_protocol;
+ extern const URLProtocol ff_prompeg_protocol;
+-extern const URLProtocol ff_rtmp_protocol;
+-extern const URLProtocol ff_rtmpe_protocol;
+-extern const URLProtocol ff_rtmps_protocol;
+-extern const URLProtocol ff_rtmpt_protocol;
+-extern const URLProtocol ff_rtmpte_protocol;
+-extern const URLProtocol ff_rtmpts_protocol;
++extern const URLProtocol ff_ffrtmp_protocol;
++extern const URLProtocol ff_ffrtmpe_protocol;
++extern const URLProtocol ff_ffrtmps_protocol;
++extern const URLProtocol ff_ffrtmpt_protocol;
++extern const URLProtocol ff_ffrtmpte_protocol;
++extern const URLProtocol ff_ffrtmpts_protocol;
+ extern const URLProtocol ff_rtp_protocol;
+ extern const URLProtocol ff_sctp_protocol;
+ extern const URLProtocol ff_srtp_protocol;
+--- a/libavformat/rtmpproto.c
++++ b/libavformat/rtmpproto.c
+@@ -2627,7 +2627,7 @@
+ static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)
+ {
+ RTMPContext *rt = s->priv_data;
+- char proto[8], hostname[256], path[1024], auth[100], *fname;
++ char *proto, tmpProto[10], hostname[256], path[1024], auth[100], *fname;
+ char *old_app, *qmark, *n, fname_buffer[1024];
+ uint8_t buf[2048];
+ int port;
+@@ -2638,7 +2638,9 @@
+
+ rt->is_input = !(flags & AVIO_FLAG_WRITE);
+
+- av_url_split(proto, sizeof(proto), auth, sizeof(auth),
++ memset(tmpProto, 0, sizeof(tmpProto));
++ proto = &tmpProto[2];
++ av_url_split(tmpProto, sizeof(tmpProto), auth, sizeof(auth),
+ hostname, sizeof(hostname), &port,
+ path, sizeof(path), s->filename);
+
+@@ -3185,9 +3187,9 @@
+ #define RTMP_PROTOCOL(flavor, uppercase) \
+ RTMP_PROTOCOL_3(flavor, CONFIG_ ## uppercase ## _PROTOCOL)
+
+-RTMP_PROTOCOL(rtmp, RTMP)
+-RTMP_PROTOCOL(rtmpe, RTMPE)
+-RTMP_PROTOCOL(rtmps, RTMPS)
+-RTMP_PROTOCOL(rtmpt, RTMPT)
+-RTMP_PROTOCOL(rtmpte, RTMPTE)
+-RTMP_PROTOCOL(rtmpts, RTMPTS)
++RTMP_PROTOCOL(ffrtmp, FFRTMP)
++RTMP_PROTOCOL(ffrtmpe, FFRTMPE)
++RTMP_PROTOCOL(ffrtmps, FFRTMPS)
++RTMP_PROTOCOL(ffrtmpt, FFRTMPT)
++RTMP_PROTOCOL(ffrtmpte, FFRTMPTE)
++RTMP_PROTOCOL(ffrtmpts, FFRTMPTS)
--- /dev/null
+--- a/libavformat/hls.c
++++ b/libavformat/hls.c
+@@ -226,6 +226,8 @@
+ int http_persistent;
+ int http_multiple;
+ int http_seekable;
++ char *key_uri_replace_old;
++ char *key_uri_replace_new;
+ int seg_max_retry;
+ AVIOContext *playlist_pb;
+ HLSCryptoContext crypto_ctx;
+@@ -1295,8 +1297,16 @@
+
+ if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) {
+ if (strcmp(seg->key, pls->key_url)) {
++ char *key_url = NULL;
+ AVIOContext *pb = NULL;
+- if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) {
++ if (NULL != c->key_uri_replace_old && \
++ NULL != c-> key_uri_replace_new && \
++ '\0' != c->key_uri_replace_old[0]) {
++ key_url = av_strireplace(seg->key, c->key_uri_replace_old, c->key_uri_replace_new);
++ } else {
++ key_url = seg->key;
++ }
++ if (open_url(pls->parent, &pb, key_url, &c->avio_opts, opts, NULL) == 0) {
+ ret = avio_read(pb, pls->key, sizeof(pls->key));
+ if (ret != sizeof(pls->key)) {
+ av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s\n",
+@@ -1308,6 +1318,8 @@
+ seg->key);
+ }
+ av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
++ if (key_url != seg->key)
++ av_free(key_url);
+ }
+ }
+
+@@ -2579,6 +2591,8 @@
+ OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
+ {"seg_max_retry", "Maximum number of times to reload a segment on error.",
+ OFFSET(seg_max_retry), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
++ { "key_uri_old", "allow to replace part of AES key uri - old", OFFSET(key_uri_replace_old), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
++ { "key_uri_new", "allow to replace part of AES key uri - new", OFFSET(key_uri_replace_new), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
+ {NULL}
+ };
+
--- /dev/null
+--- a/configure
++++ b/configure
+@@ -6132,17 +6132,10 @@
+
+ # Check toolchain ISA level
+ if enabled mips64; then
+- enabled mips64r6 && check_inline_asm mips64r6 '"dlsa $0, $0, $0, 1"' &&
+- disable mips64r2
+-
+ enabled mips64r2 && check_inline_asm mips64r2 '"dext $0, $0, 0, 1"'
+
+ disable mips32r6 && disable mips32r5 && disable mips32r2
+ else
+- enabled mips32r6 && check_inline_asm mips32r6 '"aui $0, $0, 0"' &&
+- disable mips32r5 && disable mips32r2
+-
+- enabled mips32r5 && check_inline_asm mips32r5 '"eretnc"'
+ enabled mips32r2 && check_inline_asm mips32r2 '"ext $0, $0, 0, 1"'
+
+ disable mips64r6 && disable mips64r5 && disable mips64r2
--- /dev/null
+--- a/libavcodec/aacdec_template.c
++++ b/libavcodec/aacdec_template.c
+@@ -2520,7 +2520,7 @@
+ * @param decode 1 if tool is used normally, 0 if tool is used in LTP.
+ * @param coef spectral coefficients
+ */
+-static void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
++static __attribute__((optimize(0))) void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
+ IndividualChannelStream *ics, int decode)
+ {
+ const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
+--- a/libavcodec/aacps.c
++++ b/libavcodec/aacps.c
+@@ -397,7 +397,7 @@ static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
+ par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
+ }
+
+-static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
++static void __attribute__((optimize(0))) decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
+ {
+ LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
+ LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
--- /dev/null
+--- a/libavformat/aviobuf.c
++++ b/libavformat/aviobuf.c
+@@ -34,7 +34,7 @@
+ #include "url.h"
+ #include <stdarg.h>
+
+-#define IO_BUFFER_SIZE 32768
++#define IO_BUFFER_SIZE 262144
+
+ /**
+ * Do seeks within this distance ahead of the current buffer by skipping
+@@ -580,16 +580,15 @@
+ }
+
+ /* make buffer smaller in case it ended up large after probing */
+- if (s->read_packet && ctx->orig_buffer_size &&
+- s->buffer_size > ctx->orig_buffer_size && len >= ctx->orig_buffer_size) {
++ if (s->read_packet && s->buffer_size > max_buffer_size) {
+ if (dst == s->buffer && s->buf_ptr != dst) {
+- int ret = set_buf_size(s, ctx->orig_buffer_size);
++ int ret = set_buf_size(s, max_buffer_size);
+ if (ret < 0)
+ av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
+
+ s->checksum_ptr = dst = s->buffer;
+ }
+- len = ctx->orig_buffer_size;
++ len = max_buffer_size;
+ }
+
+ len = read_packet_wrapper(s, dst, len);
--- /dev/null
+--- a/libavformat/hls.c
++++ b/libavformat/hls.c
+@@ -2298,8 +2298,10 @@
+ HLSContext *c = s->priv_data;
+ int ret, i, minplaylist = -1;
+
+- recheck_discard_flags(s, c->first_packet);
+- c->first_packet = 0;
++ if (c->first_packet) {
++ recheck_discard_flags(s, 1);
++ c->first_packet = 0;
++ }
+
+ for (i = 0; i < c->n_playlists; i++) {
+ struct playlist *pls = c->playlists[i];
--- /dev/null
+--- a/libavformat/mov.c
++++ b/libavformat/mov.c
+@@ -3966,8 +3966,10 @@
+
+ if (ctts_data_old && ctts_index_old < ctts_count_old) {
+ curr_ctts = ctts_data_old[ctts_index_old].duration;
++ /*
+ av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
+ curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
++ */
+ curr_cts += curr_ctts;
+ ctts_sample_old++;
+ if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
--- /dev/null
+--- a/libavformat/dashdec.c
++++ b/libavformat/dashdec.c
+@@ -1400,6 +1400,9 @@
+ } else {
+ num = pls->first_seq_no + (((c->publish_time - c->time_shift_buffer_depth + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
+ }
++ } else if (c->period_start && c->availability_start_time && pls->fragment_timescale) {
++ num = pls->first_seq_no + ((( get_current_time_in_sec() - (c->availability_start_time + c->period_start)) * pls->fragment_timescale) - pls->fragment_duration)/ pls->fragment_duration;
++
+ } else {
+ num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
+ }
--- /dev/null
+--- a/libavformat/rtsp.c
++++ b/libavformat/rtsp.c
+@@ -2392,6 +2392,8 @@ static int sdp_read_header(AVFormatContext *s)
+ int i, err;
+ char url[MAX_URL_SIZE];
+ AVBPrint bp;
++ const char *p, *sp="", *sources="", *sp2, *sources2;
++ char sources_buf[1024];
+
+ if (!ff_network_init())
+ return AVERROR(EIO);
+@@ -2413,6 +2415,16 @@ static int sdp_read_header(AVFormatContext *s)
+ av_bprint_finalize(&bp, NULL);
+ if (err) goto fail;
+
++ /* Search for sources= tag in original URL for rtp protocol only */
++ if (strncmp(s->url, "rtp://", 6) == 0) {
++ p = strchr(s->url, '?');
++ if (p && av_find_info_tag(sources_buf, sizeof(sources_buf), "sources", p)) {
++ /* av_log(s, AV_LOG_VERBOSE, "sdp_read_header found sources %s\n", sources_buf); */
++ sp = sources_buf;
++ sources = "&sources=";
++ }
++ }
++
+ /* open each RTP stream */
+ for (i = 0; i < rt->nb_rtsp_streams; i++) {
+ char namebuf[50];
+@@ -2432,12 +2445,22 @@ static int sdp_read_header(AVFormatContext *s)
+ av_dict_free(&opts);
+ goto fail;
+ }
++
++ /* Prepare to add sources to the url to be opened.
++ Otherwise the join to the source specific muliticast will be missing */
++ sources2 = sources;
++ sp2 = sp;
++ /* ignore sources from original URL, when sources are already set in rtsp_st */
++ if (rtsp_st->nb_include_source_addrs > 0)
++ sources2 = sp2 = "";
++
+ ff_url_join(url, sizeof(url), "rtp", NULL,
+ namebuf, rtsp_st->sdp_port,
+- "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
++ "?localport=%d&ttl=%d&connect=%d&write_to_source=%d%s%s",
+ rtsp_st->sdp_port, rtsp_st->sdp_ttl,
+ rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
+- rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
++ rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0,
++ sources2, sp2);
+
+ p = strchr(s->url, '?');
+ if (p && av_find_info_tag(buf, sizeof(buf), "localaddr", p))
--- /dev/null
+--- a/libavcodec/dxva2.c
++++ b/libavcodec/dxva2.c
+@@ -777,16 +777,18 @@
+ #if CONFIG_D3D11VA
+ if (avctx->pix_fmt == AV_PIX_FMT_D3D11)
+ return (intptr_t)frame->data[1];
+- if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
++ if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && surface) {
+ D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
+ ID3D11VideoDecoderOutputView_GetDesc((ID3D11VideoDecoderOutputView*) surface, &viewDesc);
+ return viewDesc.Texture2D.ArraySlice;
+ }
+ #endif
+ #if CONFIG_DXVA2
+- for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
+- if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
+- return i;
++ if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
++ for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
++ if (ctx->dxva2.surface[i] == surface)
++ return i;
++ }
+ }
+ #endif
+
+--- a/libavcodec/dxva2_h264.c
++++ b/libavcodec/dxva2_h264.c
+@@ -507,6 +507,14 @@
+
+ if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
+ return -1;
++
++ // Wait for an I-frame before start decoding. Workaround for ATI UVD and UVD+ GPUs
++ if (!h->got_first_iframe) {
++ if (!(ctx_pic->pp.wBitFields & (1 << 15)))
++ return -1;
++ h->got_first_iframe = 1;
++ }
++
+ ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr->f,
+ &ctx_pic->pp, sizeof(ctx_pic->pp),
+ &ctx_pic->qm, sizeof(ctx_pic->qm),
+--- a/libavcodec/h264_slice.c
++++ b/libavcodec/h264_slice.c
+@@ -978,6 +978,7 @@
+
+ h->first_field = 0;
+ h->prev_interlaced_frame = 1;
++ h->got_first_iframe = 0;
+
+ init_scan_tables(h);
+ ret = ff_h264_alloc_tables(h);
+--- a/libavcodec/h264dec.c
++++ b/libavcodec/h264dec.c
+@@ -456,6 +456,7 @@
+
+ h->next_outputed_poc = INT_MIN;
+ h->prev_interlaced_frame = 1;
++ h->got_first_iframe = 0;
+ idr(h);
+
+ h->poc.prev_frame_num = -1;
+--- a/libavcodec/h264dec.h
++++ b/libavcodec/h264dec.h
+@@ -533,6 +533,8 @@
+ * slices) anymore */
+ int setup_finished;
+
++ int got_first_iframe;
++
+ int cur_chroma_format_idc;
+ int cur_bit_depth_luma;
+ int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
+--- a/libavcodec/vaapi_h264.c
++++ b/libavcodec/vaapi_h264.c
+@@ -314,6 +314,11 @@
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int ret;
+
++ if (pic->nb_slices == 0) {
++ ret = AVERROR_INVALIDDATA;
++ goto finish;
++ }
++
+ ret = ff_vaapi_decode_issue(avctx, pic);
+ if (ret < 0)
+ goto finish;
+--- a/libavformat/bintext.c
++++ b/libavformat/bintext.c
+@@ -149,7 +149,7 @@
+ return AVPROBE_SCORE_EXTENSION + 1;
+
+ predict_width(&par, p->buf_size, got_width);
+- if (par.width < 8)
++ if (par.width <= 0)
+ return 0;
+ calculate_height(&par, p->buf_size);
+ if (par.height <= 0)
+@@ -189,8 +189,6 @@
+ next_tag_read(s, &bin->fsize);
+ if (!bin->width) {
+ predict_width(st->codecpar, bin->fsize, got_width);
+- if (st->codecpar->width < 8)
+- return AVERROR_INVALIDDATA;
+ calculate_height(st->codecpar, bin->fsize);
+ }
+ avio_seek(pb, 0, SEEK_SET);
--- /dev/null
+--- a/libavformat/avformat.h
++++ b/libavformat/avformat.h
+@@ -1030,6 +1030,10 @@
+ int64_t av_stream_get_end_pts(const AVStream *st);
+ #endif
+
++// Chromium: We use the internal field first_dts vvv
++int64_t av_stream_get_first_dts(const AVStream *st);
++// Chromium: We use the internal field first_dts ^^^
++
+ #define AV_PROGRAM_RUNNING 1
+
+ /**
+--- a/libavformat/utils.c
++++ b/libavformat/utils.c
+@@ -100,6 +100,13 @@
+ return pkt->size > orig_size ? pkt->size - orig_size : ret;
+ }
+
++// Chromium: We use the internal field first_dts vvv
++int64_t av_stream_get_first_dts(const AVStream *st)
++{
++ return cffstream(st)->first_dts;
++}
++// Chromium: We use the internal field first_dts ^^^
++
+ int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
+ {
+ #if FF_API_INIT_PACKET
--- /dev/null
+--- a/libavformat/avio.c
++++ b/libavformat/avio.c
+@@ -171,12 +171,12 @@
+ (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value)));
+ av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
+ (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value)));
+-
++/*
+ if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) {
+ av_log(uc, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", uc->prot->name, uc->protocol_whitelist);
+ return AVERROR(EINVAL);
+ }
+-
++*/
+ if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) {
+ av_log(uc, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", uc->prot->name, uc->protocol_blacklist);
+ return AVERROR(EINVAL);
--- /dev/null
+--- a/doc/demuxers.texi
++++ b/doc/demuxers.texi
+@@ -281,7 +281,11 @@
+ @table @option
+
+ @item cenc_decryption_key
+-16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
++Default 16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
++
++ at item cenc_decryption_keys
++Dictionary of 16-byte key ID => 16-byte key, both in hex, to decrypt files encrypted using ISO Common Encryption
++(CENC/AES-128 CTR; ISO/IEC 23001-7).
+
+ @end table
+
+@@ -769,7 +773,11 @@
+ specify.
+
+ @item decryption_key
+-16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
++Default 16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
++
++ at item decryption_keys
++Dictionary of 16-byte key ID => 16-byte key, both in hex, to decrypt files encrypted using ISO Common Encryption
++(CENC/AES-128 CTR; ISO/IEC 23001-7).
+
+ @item max_stts_delta
+ Very high sample deltas written in a trak's stts box may occasionally be intended but usually they are written in
+--- a/libavformat/dashdec.c
++++ b/libavformat/dashdec.c
+@@ -153,6 +153,7 @@
+ AVDictionary *avio_opts;
+ int max_url_size;
+ char *cenc_decryption_key;
++ char *cenc_decryption_keys;
+
+ /* Flags for init section*/
+ int is_init_section_common_video;
+@@ -1906,6 +1907,8 @@
+
+ if (c->cenc_decryption_key)
+ av_dict_set(&in_fmt_opts, "decryption_key", c->cenc_decryption_key, 0);
++ if (c->cenc_decryption_keys)
++ av_dict_set(&in_fmt_opts, "decryption_keys", c->cenc_decryption_keys, 0);
+
+ // provide additional information from mpd if available
+ ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts); //pls->init_section->url
+@@ -2347,7 +2350,8 @@
+ OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
+ {.str = "aac,m4a,m4s,m4v,mov,mp4,webm,ts"},
+ INT_MIN, INT_MAX, FLAGS},
+- { "cenc_decryption_key", "Media decryption key (hex)", OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
++ { "cenc_decryption_key", "Media default decryption key (hex)", OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
++ { "cenc_decryption_keys", "Media decryption keys by KID (hex)", OFFSET(cenc_decryption_keys), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
+ {NULL}
+ };
+
+--- a/libavformat/isom.h
++++ b/libavformat/isom.h
+@@ -312,8 +312,8 @@
+ void *audible_iv;
+ int audible_iv_size;
+ struct AVAES *aes_decrypt;
+- uint8_t *decryption_key;
+- int decryption_key_len;
++ uint8_t *decryption_default_key;
++ int decryption_default_key_len;
+ int enable_drefs;
+ int32_t movie_display_matrix[3][3]; ///< display matrix from mvhd
+ int have_read_mfra_size;
+@@ -328,6 +328,7 @@
+ } *avif_info;
+ int avif_info_size;
+ int interleaved_read;
++ AVDictionary* decryption_keys;
+ } MOVContext;
+
+ int ff_mp4_read_descr_len(AVIOContext *pb);
+--- a/libavformat/mov.c
++++ b/libavformat/mov.c
+@@ -7130,19 +7130,62 @@
+ return 0;
+ }
+
++static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
++ AVDictionaryEntry *key_entry_hex;
++ char kid_hex[16*2+1];
++
++ if (c->decryption_default_key && c->decryption_default_key_len != len) {
++ av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
++ return -1;
++ }
++
++ if (!c->decryption_keys) {
++ av_assert0(c->decryption_default_key);
++ memcpy(out, c->decryption_default_key, len);
++ return 0;
++ }
++
++ if (sample->key_id_size != 16) {
++ av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
++ return -1;
++ }
++
++ ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
++ key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
++ if (!key_entry_hex) {
++ if (!c->decryption_default_key) {
++ av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
++ return -1;
++ }
++ memcpy(out, c->decryption_default_key, len);
++ return 0;
++ }
++ if (strlen(key_entry_hex->value) != len*2) {
++ return -1;
++ }
++ ff_hex_to_data(out, key_entry_hex->value);
++ return 0;
++}
++
+ static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
+ {
+ int i, ret;
+ int bytes_of_protected_data;
++ uint8_t decryption_key[AES_CTR_KEY_SIZE];
+
+ if (!sc->cenc.aes_ctr) {
++ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
++ if (ret < 0) {
++ return ret;
++ }
++
+ /* 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);
++ ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
+ if (ret < 0) {
+ return ret;
+ }
+@@ -7188,15 +7231,21 @@
+ int i, ret;
+ int num_of_encrypted_blocks;
+ uint8_t iv[16];
++ uint8_t decryption_key[16];
+
+ if (!sc->cenc.aes_ctx) {
++ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
++ if (ret < 0) {
++ return ret;
++ }
++
+ /* 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);
++ ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
+ if (ret < 0) {
+ return ret;
+ }
+@@ -7247,15 +7296,21 @@
+ {
+ int i, ret, rem_bytes;
+ uint8_t *data;
++ uint8_t decryption_key[AES_CTR_KEY_SIZE];
+
+ if (!sc->cenc.aes_ctr) {
++ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
++ if (ret < 0) {
++ return ret;
++ }
++
+ /* 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);
++ ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
+ if (ret < 0) {
+ return ret;
+ }
+@@ -7313,15 +7368,21 @@
+ int i, ret, rem_bytes;
+ uint8_t iv[16];
+ uint8_t *data;
++ uint8_t decryption_key[16];
+
+ if (!sc->cenc.aes_ctx) {
++ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
++ if (ret < 0) {
++ return ret;
++ }
++
+ /* 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);
++ ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
+ if (ret < 0) {
+ return ret;
+ }
+@@ -7464,7 +7525,7 @@
+ return AVERROR_INVALIDDATA;
+ }
+
+- if (mov->decryption_key) {
++ if (mov->decryption_keys || mov->decryption_default_key) {
+ return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
+ } else {
+ size_t size;
+@@ -8613,12 +8674,6 @@
+ MOVAtom atom = { AV_RL32("root") };
+ int i;
+
+- if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
+- av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
+- mov->decryption_key_len, AES_CTR_KEY_SIZE);
+- return AVERROR(EINVAL);
+- }
+-
+ mov->fc = s;
+ mov->trak_index = -1;
+ /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
+@@ -9317,7 +9372,8 @@
+ "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
+ AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
+ .flags = AV_OPT_FLAG_DECODING_PARAM },
+- { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
++ { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
++ { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
+ { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
+ {.i64 = 0}, 0, 1, FLAGS },
+ { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM },
+--- a/tests/fate/mov.mak
++++ b/tests/fate/mov.mak
+@@ -8,6 +8,9 @@
+ fate-mov-3elist-encrypted \
+ fate-mov-frag-encrypted \
+ fate-mov-tenc-only-encrypted \
++ fate-mov-3elist-encrypted-kid \
++ fate-mov-frag-encrypted-kid \
++ fate-mov-tenc-only-encrypted-kid \
+ fate-mov-invalid-elst-entry-count \
+ fate-mov-gpmf-remux \
+ fate-mov-440hz-10ms \
+@@ -57,6 +60,15 @@ fate-mov-frag-encrypted: CMD = framemd5 -decryption_key 123456789012345678901234
+ # Full-sample encryption and constant IV using only tenc atom (no senc/saio/saiz).
+ fate-mov-tenc-only-encrypted: CMD = framemd5 -decryption_key 12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-tenc-only-encrypted.mp4
+
++# Edit list with encryption, using the decryption_keys option.
++fate-mov-3elist-encrypted-kid: CMD = framemd5 -decryption_keys 12345678901234567890123456789012=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-3elist-encrypted.mov
++
++# Fragmented encryption with senc boxes in movie fragments, using the decryption_keys option.
++fate-mov-frag-encrypted-kid: CMD = framemd5 -decryption_keys abba271e8bcf552bbd2e86a434a9a5d9=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-frag-encrypted.mp4
++
++# Full-sample encryption and constant IV using only tenc atom (no senc/saio/saiz), using the decryption_keys option.
++fate-mov-tenc-only-encrypted-kid: CMD = framemd5 -decryption_keys abba271e8bcf552bbd2e86a434a9a5d9=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-tenc-only-encrypted.mp4
++
+ # Makes sure that the CTTS is also modified when we fix avindex in mov.c while parsing edit lists.
+ fate-mov-elist-starts-ctts-2ndsample: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-elist-starts-ctts-2ndsample.mov
+
+--- /dev/null
++++ b/tests/ref/fate/mov-3elist-encrypted-kid
+@@ -0,0 +1,57 @@
++#format: frame checksums
++#version: 2
++#hash: MD5
++#tb 0: 1/24
++#media_type 0: video
++#codec_id 0: rawvideo
++#dimensions 0: 640x480
++#sar 0: 0/1
++#stream#, dts, pts, duration, size, hash
++0, 0, 0, 1, 460800, 80fbbdec589e15e6c493b44d243f92a9
++0, 1, 1, 1, 460800, f4b23293bb2ecf69cc3570853d8c56a1
++0, 2, 2, 1, 460800, 0c03ce2c1c6ec405d7455465ecd559a3
++0, 3, 3, 1, 460800, 7921791695537fba2c3c123da4834cb9
++0, 4, 4, 1, 460800, 30c8e2903a561b84d4cbaf95c668d236
++0, 5, 5, 1, 460800, 7ff42e998217c17592ddf6b584f26cef
++0, 6, 6, 1, 460800, 5e402c48bf097db2d31b82bb4194a382
++0, 7, 7, 1, 460800, 824c49e92c8ae6d99a0207b514dd756c
++0, 8, 8, 1, 460800, 24f189216a1d9cf2313b2d6dbe3dbdd3
++0, 9, 9, 1, 460800, 519179a8e74275d26b183374637e003f
++0, 10, 10, 1, 460800, f18331ddcef0adf5b069bfa98baf8db4
++0, 11, 11, 1, 460800, 081f61688690d47dbdddd5384e5d5a70
++0, 12, 12, 1, 460800, 90dbf019b9035433371a8df41a9268b7
++0, 13, 13, 1, 460800, bb5adfb9c66732898b34186eca1667ba
++0, 14, 14, 1, 460800, cc08cfd64f37783ecddaf143f6ad78bc
++0, 15, 15, 1, 460800, b8ae21d024fe4df903d56f4521993c72
++0, 16, 16, 1, 460800, b45a99907f045dcadf0a2befc11555e3
++0, 17, 17, 1, 460800, 603ba935845e65ab6cccbbec88bbf60d
++0, 18, 18, 1, 460800, df80c8d3e6a77258a306903f17995a18
++0, 19, 19, 1, 460800, 4b7e90c0a5fd0e0cd958d47f0afac636
++0, 20, 20, 1, 460800, 9feb6e36182f1745be6387edea240eb6
++0, 21, 21, 1, 460800, 86e6de4bd0a5ff7558f4cf6c1ec3930d
++0, 22, 22, 1, 460800, 726b69df77edbe7b503d4698656d1320
++0, 23, 23, 1, 460800, d282fb7a953ac205b0a43d00c2d60a33
++0, 24, 24, 1, 460800, eece3daa70cc20208dd75d91ac84c8fd
++0, 25, 25, 1, 460800, c86d23e73bcce351fc315fb1f13348da
++0, 26, 26, 1, 460800, 93497b4f7c5ad9d61212239b7c9d2770
++0, 27, 27, 1, 460800, eb217d2c12de67903835a8c58f620488
++0, 28, 28, 1, 460800, d966480867bb54c8cd044f18388ed486
++0, 29, 29, 1, 460800, 3ea6207942b3181fdd8e8aa6cae1062a
++0, 30, 30, 1, 460800, 2620df54aca086ec0fb9527c6e6f5135
++0, 31, 31, 1, 460800, 43bb7320f0bb583188dc965ddbfade90
++0, 32, 32, 1, 460800, 0cddaa04645f804e02f65b0836412113
++0, 33, 33, 1, 460800, 83b2dc95807289d7f4a4632bf18c2e97
++0, 34, 34, 1, 460800, 98134d0e41e6dd12827049ccf33b4669
++0, 35, 35, 1, 460800, 56f55631731fa39c7acbab0afeb2eb1b
++0, 36, 36, 1, 460800, 379c1105be09d836a515dc909455ddf4
++0, 37, 37, 1, 460800, 1df87c47e9d98731faf1c3885b77e5da
++0, 38, 38, 1, 460800, 9a8734bcbfdb4d97e530683b8b556a26
++0, 39, 39, 1, 460800, c7a7990d0cddc5adfbe27da7a42e025e
++0, 40, 40, 1, 460800, 0c81e46011e03be410feaf056207fd55
++0, 41, 41, 1, 460800, ca76e4e63016ff29d8aeeb9cb053bb6c
++0, 42, 42, 1, 460800, cebfbe299c17c1f8fc1e6b189555c3c2
++0, 43, 43, 1, 460800, 4f002c5feca5e75f07089e0df47507dd
++0, 44, 44, 1, 460800, c5fd83fc4a745abee9b3d9a6eec9dd3e
++0, 45, 45, 1, 460800, 57d9bad9b45aa2746de5d8bdc2c24969
++0, 46, 46, 1, 460800, 9831673ad7dec167af4a959f64258949
++0, 47, 47, 1, 460800, 77a1cb208f70f51bcb01e28d8cba73b4
+--- /dev/null
++++ b/tests/ref/fate/mov-frag-encrypted-kid
+@@ -0,0 +1,57 @@
++#format: frame checksums
++#version: 2
++#hash: MD5
++#tb 0: 1/24
++#media_type 0: video
++#codec_id 0: rawvideo
++#dimensions 0: 120x52
++#sar 0: 544/545
++#stream#, dts, pts, duration, size, hash
++0, 0, 0, 1, 9360, 920bdc277a6a31c1daed9aca44b10caf
++0, 1, 1, 1, 9360, f1c0b61fef593de57cb97be7fa846569
++0, 2, 2, 1, 9360, 6ef32d9d4398355aebf6d3fb11d51d3f
++0, 3, 3, 1, 9360, d38fd3ef1e5a92fc109b8dd9eb6dadeb
++0, 4, 4, 1, 9360, 54cc0c8a25d2f14f32663837d5e646f1
++0, 5, 5, 1, 9360, b4b6829726dc3decb8b80ba0c35bcf30
++0, 6, 6, 1, 9360, fca3f941e60a2f0a4ce30d5e0efbec3c
++0, 7, 7, 1, 9360, cda6e26b6c1039ff3d229b262c9210c3
++0, 8, 8, 1, 9360, f0d69255e3a27a8b4ae8a4b7b210929d
++0, 9, 9, 1, 9360, 12cb23dd4e32af9c3b35f943714e3fdd
++0, 10, 10, 1, 9360, 082aaf3216124ddcecb422fe5c832e82
++0, 11, 11, 1, 9360, ff37bb8cd6bd0412a3b3cb45db54afc9
++0, 12, 12, 1, 9360, dfb9085441575732844b6c2f05d5f542
++0, 13, 13, 1, 9360, 0017100feaaa9fc7eacd2447d50d7542
++0, 14, 14, 1, 9360, 4e2f1b8c4e04c59934c2f58541e62613
++0, 15, 15, 1, 9360, 27a44dfea7cd2d30e488194c34ab473c
++0, 16, 16, 1, 9360, fc7b56bd95e990a33cf575d1ef820902
++0, 17, 17, 1, 9360, fa2d1609e69714dffc410e65f3c8b755
++0, 18, 18, 1, 9360, 705d7429f447cb13febe202d567795f2
++0, 19, 19, 1, 9360, 234802ce86e868faaf2cd40a286846ea
++0, 20, 20, 1, 9360, 2f0354b40d211d0a4ade4568bea4f85e
++0, 21, 21, 1, 9360, e96af3b6c0cc931463ca77d6be0f1148
++0, 22, 22, 1, 9360, 04a904d798361959971361401879c7e4
++0, 23, 23, 1, 9360, 2f119642340df6d25362b5590ded46b7
++0, 24, 24, 1, 9360, 5993fca2e60050706f857ac76e48f386
++0, 25, 25, 1, 9360, 2ff3b5775fed3d527bfbbeea786787fe
++0, 26, 26, 1, 9360, 42024dbe23d3fb5b0d8987ae1ce390a8
++0, 27, 27, 1, 9360, d804204f0bd9db5f6a758e2c934d9e38
++0, 28, 28, 1, 9360, e322712e6e34c58ec1a2ab5e2c1e3bfe
++0, 29, 29, 1, 9360, 3975bd1a5f6a6b6260276777f9de611e
++0, 30, 30, 1, 9360, 4388f0412efc6310706a7cdedc859ea9
++0, 31, 31, 1, 9360, b4b9a11b0b86635267345a569640e8d4
++0, 32, 32, 1, 9360, 31879c7b8d6b67a4209ffde786bb8cb4
++0, 33, 33, 1, 9360, 4b6dc02d7c889fe4abd4e013b25f585a
++0, 34, 34, 1, 9360, dc73aae82bd39a1220d1106c8d3e8252
++0, 35, 35, 1, 9360, 54c7dfbd49f312806f6c1a89f7c2c36f
++0, 36, 36, 1, 9360, 150abc64f8994d444a521ea90570443c
++0, 37, 37, 1, 9360, d277cdc7dcadbe0016f2e950459e7ebf
++0, 38, 38, 1, 9360, 2196bf338ead90ea54687b85c73c8229
++0, 39, 39, 1, 9360, 53ce5da5365abc0bd3217dd98e7c465d
++0, 40, 40, 1, 9360, 34ee9832aea55c0c4e6f4381c413c10e
++0, 41, 41, 1, 9360, 1769c7b5849e4681119067a06ac29a4f
++0, 42, 42, 1, 9360, 71f53df739ef283a5184c91ef4b158e8
++0, 43, 43, 1, 9360, d2d394739e9a59c06f0354c16843cb63
++0, 44, 44, 1, 9360, d8e458e92ae29344505a24a3059fc584
++0, 45, 45, 1, 9360, 0f1b11a09911851b798df2ef76253a7f
++0, 46, 46, 1, 9360, 5c4a9f22baecf4e749c0d5c65a4f1007
++0, 47, 47, 1, 9360, 3e2b7e7262fdca08d9d1ef6070125c4b
+--- /dev/null
++++ b/tests/ref/fate/mov-tenc-only-encrypted-kid
+@@ -0,0 +1,57 @@
++#format: frame checksums
++#version: 2
++#hash: MD5
++#tb 0: 1/24
++#media_type 0: video
++#codec_id 0: rawvideo
++#dimensions 0: 1024x436
++#sar 0: 1/1
++#stream#, dts, pts, duration, size, hash
++0, 0, 0, 1, 669696, f48f296a85eda5ba069dc851a3228bef
++0, 1, 1, 1, 669696, a50c5f69bfa3387d49b5bdf738e6529c
++0, 2, 2, 1, 669696, 05061299003760f6a4795b408f72aa31
++0, 3, 3, 1, 669696, 2572119f0b0cdd83f8a7e06252cecd3b
++0, 4, 4, 1, 669696, 29fe6a6bdb4a69018e318886a297f07e
++0, 5, 5, 1, 669696, e8233c7fbaecfbff965c7dfdd3982b1b
++0, 6, 6, 1, 669696, d9259df9880ff5d4a4b38282e67f407b
++0, 7, 7, 1, 669696, 3e8d795195038993503ea9ab6984c915
++0, 8, 8, 1, 669696, bc4e2d253b715a34f85aae1b080e3460
++0, 9, 9, 1, 669696, 09aba8b3a96f53f9268e7420a10bfab6
++0, 10, 10, 1, 669696, 179447977dd580da8b35fb5310a809ca
++0, 11, 11, 1, 669696, 7a0eea9d54577990345f5705ab9882be
++0, 12, 12, 1, 669696, 5bb96eb76f461825740e5938456df759
++0, 13, 13, 1, 669696, bd4ac4a760ead774b9422a27dc071964
++0, 14, 14, 1, 669696, 1cc05f760a9b751fc89e77f2bcc97259
++0, 15, 15, 1, 669696, 825d0dee6f0174ba7102892c7de30b4d
++0, 16, 16, 1, 669696, d26a2ef5267f6bb03c4e1d8514eee0df
++0, 17, 17, 1, 669696, c916ffdeadca76596a8f7fd47914b5ef
++0, 18, 18, 1, 669696, 6e085acfa7fee0658ea0ae6188274c17
++0, 19, 19, 1, 669696, 1e95fa5b3561283f05bf0bd44cb91721
++0, 20, 20, 1, 669696, 37e3d135aba9dfb8b87e441753115374
++0, 21, 21, 1, 669696, 9c398310e8564491de624393c16265ce
++0, 22, 22, 1, 669696, c87209e4d2617bc2ab40a75f455f09da
++0, 23, 23, 1, 669696, 2679c2f8d1d1af21982e245945c1ee60
++0, 24, 24, 1, 669696, 6151ab4781f31c5beb66b356ad547122
++0, 25, 25, 1, 669696, f7ef6293bfb3a6a329061cb6a5ed5a38
++0, 26, 26, 1, 669696, 2f6e666d14dfc407ca0c0f347b13eb08
++0, 27, 27, 1, 669696, 3454fa1730d79b1aa8dbbc865dc150f4
++0, 28, 28, 1, 669696, e93dc683e2453419a0419ab9af0f8f95
++0, 29, 29, 1, 669696, 031eb3154f7f83cf86d42bee66be9cf7
++0, 30, 30, 1, 669696, 1205c36723e88811206c68892d3aaed6
++0, 31, 31, 1, 669696, 7dd7a8a19dcd73b31ddc6a6d0c597a42
++0, 32, 32, 1, 669696, 7c91115368ea2531262a1197468bc3f4
++0, 33, 33, 1, 669696, 3cf6d9ba385e0fff76da33299ed5380c
++0, 34, 34, 1, 669696, 859fc8c3ef049e3c1175a85fb0a90a3d
++0, 35, 35, 1, 669696, 1d09ce6c7027103d99a4d5799f6e72ab
++0, 36, 36, 1, 669696, 3dcb8357408ac88abd734128d8f5dd6f
++0, 37, 37, 1, 669696, 4dafce137a0a5178f6efaec878e64d36
++0, 38, 38, 1, 669696, 44c478f29a1399ed03275a7357f57d48
++0, 39, 39, 1, 669696, 6e9edaac7414c0e14591ac3d4d0b1ac4
++0, 40, 40, 1, 669696, 522e4aaeea0825da27f631a9e690d654
++0, 41, 41, 1, 669696, 85f2502a718440834c40051d30f8a65e
++0, 42, 42, 1, 669696, ae8816f7bd4645ef1a17ee6d09b4c8d2
++0, 43, 43, 1, 669696, 914b006fa92f1eb3e590245749f6810d
++0, 44, 44, 1, 669696, 9406901542e94c429dff46108782ed69
++0, 45, 45, 1, 669696, 324c13641c39eef5c476023e358c0391
++0, 46, 46, 1, 669696, 4058e886e17c22e4eb9da1dd0d6ad891
++0, 47, 47, 1, 669696, 9edf9cd15eea985b42fd1f5035b1d693
+--
+++ /dev/null
-diff --git a/libavutil/log.c b/libavutil/log.c
-index 5948e50467..528eaa728c 100644
---- a/libavutil/log.c
-+++ b/libavutil/log.c
-@@ -53,7 +53,7 @@ static AVMutex mutex = AV_MUTEX_INITIALIZER;
- #define BACKTRACE_LOGLEVEL AV_LOG_ERROR
- #endif
-
--static int av_log_level = AV_LOG_INFO;
-+static int av_log_level = AV_LOG_ERROR; // NOT WORKING for libs
- static int flags;
-
- #define NB_LEVELS 8
-@@ -408,10 +408,6 @@ static void (*av_log_callback)(void*, int, const char*, va_list) =
-
- void av_log(void* avcl, int level, const char *fmt, ...)
- {
-- va_list vl;
-- va_start(vl, fmt);
-- av_vlog(avcl, level, fmt, vl);
-- va_end(vl);
- }
-
- void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...)
+++ /dev/null
---- a/libavformat/mpegts.c
-+++ b/libavformat/mpegts.c
-@@ -1041,10 +1041,12 @@
- pes->buffer = NULL;
- reset_pes_packet_state(pes);
-
-+ /*
- sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
- if (!sd)
- return AVERROR(ENOMEM);
- *sd = pes->stream_id;
-+ */
-
- return 0;
- }
+++ /dev/null
---- a/configure
-+++ b/configure
-@@ -3615,10 +3615,8 @@
- # protocols
- async_protocol_deps="threads"
- bluray_protocol_deps="libbluray"
--ffrtmpcrypt_protocol_conflict="librtmp_protocol"
- ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl mbedtls"
- ffrtmpcrypt_protocol_select="tcp_protocol"
--ffrtmphttp_protocol_conflict="librtmp_protocol"
- ffrtmphttp_protocol_select="http_protocol"
- ftp_protocol_select="tcp_protocol"
- gopher_protocol_select="tcp_protocol"
-@@ -3632,20 +3630,18 @@
- icecast_protocol_select="http_protocol"
- mmsh_protocol_select="http_protocol"
- mmst_protocol_select="network"
--rtmp_protocol_conflict="librtmp_protocol"
--rtmp_protocol_select="tcp_protocol"
--rtmp_protocol_suggest="zlib"
--rtmpe_protocol_select="ffrtmpcrypt_protocol"
--rtmpe_protocol_suggest="zlib"
--rtmps_protocol_conflict="librtmp_protocol"
--rtmps_protocol_select="tls_protocol"
--rtmps_protocol_suggest="zlib"
--rtmpt_protocol_select="ffrtmphttp_protocol"
--rtmpt_protocol_suggest="zlib"
--rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
--rtmpte_protocol_suggest="zlib"
--rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
--rtmpts_protocol_suggest="zlib"
-+ffrtmp_protocol_select="tcp_protocol"
-+ffrtmp_protocol_suggest="zlib"
-+ffrtmpe_protocol_select="ffrtmpcrypt_protocol"
-+ffrtmpe_protocol_suggest="zlib"
-+ffrtmps_protocol_select="tls_protocol"
-+ffrtmps_protocol_suggest="zlib"
-+ffrtmpt_protocol_select="ffrtmphttp_protocol"
-+ffrtmpt_protocol_suggest="zlib"
-+ffrtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
-+ffrtmpte_protocol_suggest="zlib"
-+ffrtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
-+ffrtmpts_protocol_suggest="zlib"
- rtp_protocol_select="udp_protocol"
- schannel_conflict="openssl gnutls libtls mbedtls"
- sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags"
---- a/libavformat/Makefile
-+++ b/libavformat/Makefile
-@@ -676,12 +676,12 @@
- OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf_tags.o
- OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
- OBJS-$(CONFIG_PROMPEG_PROTOCOL) += prompeg.o
--OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPTE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPTS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPT_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPTE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPTS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
- OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o ip.o
- OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o
- OBJS-$(CONFIG_SRTP_PROTOCOL) += srtpproto.o srtp.o
---- a/libavformat/protocols.c
-+++ b/libavformat/protocols.c
-@@ -48,12 +48,12 @@
- extern const URLProtocol ff_md5_protocol;
- extern const URLProtocol ff_pipe_protocol;
- extern const URLProtocol ff_prompeg_protocol;
--extern const URLProtocol ff_rtmp_protocol;
--extern const URLProtocol ff_rtmpe_protocol;
--extern const URLProtocol ff_rtmps_protocol;
--extern const URLProtocol ff_rtmpt_protocol;
--extern const URLProtocol ff_rtmpte_protocol;
--extern const URLProtocol ff_rtmpts_protocol;
-+extern const URLProtocol ff_ffrtmp_protocol;
-+extern const URLProtocol ff_ffrtmpe_protocol;
-+extern const URLProtocol ff_ffrtmps_protocol;
-+extern const URLProtocol ff_ffrtmpt_protocol;
-+extern const URLProtocol ff_ffrtmpte_protocol;
-+extern const URLProtocol ff_ffrtmpts_protocol;
- extern const URLProtocol ff_rtp_protocol;
- extern const URLProtocol ff_sctp_protocol;
- extern const URLProtocol ff_srtp_protocol;
---- a/libavformat/rtmpproto.c
-+++ b/libavformat/rtmpproto.c
-@@ -2627,7 +2627,7 @@
- static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)
- {
- RTMPContext *rt = s->priv_data;
-- char proto[8], hostname[256], path[1024], auth[100], *fname;
-+ char *proto, tmpProto[10], hostname[256], path[1024], auth[100], *fname;
- char *old_app, *qmark, *n, fname_buffer[1024];
- uint8_t buf[2048];
- int port;
-@@ -2638,7 +2638,9 @@
-
- rt->is_input = !(flags & AVIO_FLAG_WRITE);
-
-- av_url_split(proto, sizeof(proto), auth, sizeof(auth),
-+ memset(tmpProto, 0, sizeof(tmpProto));
-+ proto = &tmpProto[2];
-+ av_url_split(tmpProto, sizeof(tmpProto), auth, sizeof(auth),
- hostname, sizeof(hostname), &port,
- path, sizeof(path), s->filename);
-
-@@ -3185,9 +3187,9 @@
- #define RTMP_PROTOCOL(flavor, uppercase) \
- RTMP_PROTOCOL_3(flavor, CONFIG_ ## uppercase ## _PROTOCOL)
-
--RTMP_PROTOCOL(rtmp, RTMP)
--RTMP_PROTOCOL(rtmpe, RTMPE)
--RTMP_PROTOCOL(rtmps, RTMPS)
--RTMP_PROTOCOL(rtmpt, RTMPT)
--RTMP_PROTOCOL(rtmpte, RTMPTE)
--RTMP_PROTOCOL(rtmpts, RTMPTS)
-+RTMP_PROTOCOL(ffrtmp, FFRTMP)
-+RTMP_PROTOCOL(ffrtmpe, FFRTMPE)
-+RTMP_PROTOCOL(ffrtmps, FFRTMPS)
-+RTMP_PROTOCOL(ffrtmpt, FFRTMPT)
-+RTMP_PROTOCOL(ffrtmpte, FFRTMPTE)
-+RTMP_PROTOCOL(ffrtmpts, FFRTMPTS)
+++ /dev/null
---- a/libavformat/hls.c
-+++ b/libavformat/hls.c
-@@ -226,6 +226,8 @@
- int http_persistent;
- int http_multiple;
- int http_seekable;
-+ char *key_uri_replace_old;
-+ char *key_uri_replace_new;
- int seg_max_retry;
- AVIOContext *playlist_pb;
- HLSCryptoContext crypto_ctx;
-@@ -1295,8 +1297,16 @@
-
- if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) {
- if (strcmp(seg->key, pls->key_url)) {
-+ char *key_url = NULL;
- AVIOContext *pb = NULL;
-- if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) {
-+ if (NULL != c->key_uri_replace_old && \
-+ NULL != c-> key_uri_replace_new && \
-+ '\0' != c->key_uri_replace_old[0]) {
-+ key_url = av_strireplace(seg->key, c->key_uri_replace_old, c->key_uri_replace_new);
-+ } else {
-+ key_url = seg->key;
-+ }
-+ if (open_url(pls->parent, &pb, key_url, &c->avio_opts, opts, NULL) == 0) {
- ret = avio_read(pb, pls->key, sizeof(pls->key));
- if (ret != sizeof(pls->key)) {
- av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s\n",
-@@ -1308,6 +1318,8 @@
- seg->key);
- }
- av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
-+ if (key_url != seg->key)
-+ av_free(key_url);
- }
- }
-
-@@ -2579,6 +2591,8 @@
- OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
- {"seg_max_retry", "Maximum number of times to reload a segment on error.",
- OFFSET(seg_max_retry), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
-+ { "key_uri_old", "allow to replace part of AES key uri - old", OFFSET(key_uri_replace_old), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
-+ { "key_uri_new", "allow to replace part of AES key uri - new", OFFSET(key_uri_replace_new), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
- {NULL}
- };
-
+++ /dev/null
---- a/configure
-+++ b/configure
-@@ -6132,17 +6132,10 @@
-
- # Check toolchain ISA level
- if enabled mips64; then
-- enabled mips64r6 && check_inline_asm mips64r6 '"dlsa $0, $0, $0, 1"' &&
-- disable mips64r2
--
- enabled mips64r2 && check_inline_asm mips64r2 '"dext $0, $0, 0, 1"'
-
- disable mips32r6 && disable mips32r5 && disable mips32r2
- else
-- enabled mips32r6 && check_inline_asm mips32r6 '"aui $0, $0, 0"' &&
-- disable mips32r5 && disable mips32r2
--
-- enabled mips32r5 && check_inline_asm mips32r5 '"eretnc"'
- enabled mips32r2 && check_inline_asm mips32r2 '"ext $0, $0, 0, 1"'
-
- disable mips64r6 && disable mips64r5 && disable mips64r2
+++ /dev/null
---- a/libavcodec/aacdec_template.c
-+++ b/libavcodec/aacdec_template.c
-@@ -2520,7 +2520,7 @@
- * @param decode 1 if tool is used normally, 0 if tool is used in LTP.
- * @param coef spectral coefficients
- */
--static void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
-+static __attribute__((optimize(0))) void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
- IndividualChannelStream *ics, int decode)
- {
- const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
---- a/libavcodec/aacps.c
-+++ b/libavcodec/aacps.c
-@@ -397,7 +397,7 @@ static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
- par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
- }
-
--static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
-+static void __attribute__((optimize(0))) decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
- {
- LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
- LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
+++ /dev/null
---- a/libavformat/aviobuf.c
-+++ b/libavformat/aviobuf.c
-@@ -34,7 +34,7 @@
- #include "url.h"
- #include <stdarg.h>
-
--#define IO_BUFFER_SIZE 32768
-+#define IO_BUFFER_SIZE 262144
-
- /**
- * Do seeks within this distance ahead of the current buffer by skipping
-@@ -580,16 +580,15 @@
- }
-
- /* make buffer smaller in case it ended up large after probing */
-- if (s->read_packet && ctx->orig_buffer_size &&
-- s->buffer_size > ctx->orig_buffer_size && len >= ctx->orig_buffer_size) {
-+ if (s->read_packet && s->buffer_size > max_buffer_size) {
- if (dst == s->buffer && s->buf_ptr != dst) {
-- int ret = set_buf_size(s, ctx->orig_buffer_size);
-+ int ret = set_buf_size(s, max_buffer_size);
- if (ret < 0)
- av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
-
- s->checksum_ptr = dst = s->buffer;
- }
-- len = ctx->orig_buffer_size;
-+ len = max_buffer_size;
- }
-
- len = read_packet_wrapper(s, dst, len);
+++ /dev/null
---- a/libavformat/hls.c
-+++ b/libavformat/hls.c
-@@ -2298,8 +2298,10 @@
- HLSContext *c = s->priv_data;
- int ret, i, minplaylist = -1;
-
-- recheck_discard_flags(s, c->first_packet);
-- c->first_packet = 0;
-+ if (c->first_packet) {
-+ recheck_discard_flags(s, 1);
-+ c->first_packet = 0;
-+ }
-
- for (i = 0; i < c->n_playlists; i++) {
- struct playlist *pls = c->playlists[i];
+++ /dev/null
---- a/libavformat/mov.c
-+++ b/libavformat/mov.c
-@@ -3966,8 +3966,10 @@
-
- if (ctts_data_old && ctts_index_old < ctts_count_old) {
- curr_ctts = ctts_data_old[ctts_index_old].duration;
-+ /*
- av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
- curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
-+ */
- curr_cts += curr_ctts;
- ctts_sample_old++;
- if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
+++ /dev/null
---- a/libavformat/dashdec.c
-+++ b/libavformat/dashdec.c
-@@ -1400,6 +1400,9 @@
- } else {
- num = pls->first_seq_no + (((c->publish_time - c->time_shift_buffer_depth + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
- }
-+ } else if (c->period_start && c->availability_start_time && pls->fragment_timescale) {
-+ num = pls->first_seq_no + ((( get_current_time_in_sec() - (c->availability_start_time + c->period_start)) * pls->fragment_timescale) - pls->fragment_duration)/ pls->fragment_duration;
-+
- } else {
- num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
- }
+++ /dev/null
---- a/libavformat/rtsp.c
-+++ b/libavformat/rtsp.c
-@@ -2392,6 +2392,8 @@ static int sdp_read_header(AVFormatContext *s)
- int i, err;
- char url[MAX_URL_SIZE];
- AVBPrint bp;
-+ const char *p, *sp="", *sources="", *sp2, *sources2;
-+ char sources_buf[1024];
-
- if (!ff_network_init())
- return AVERROR(EIO);
-@@ -2413,6 +2415,16 @@ static int sdp_read_header(AVFormatContext *s)
- av_bprint_finalize(&bp, NULL);
- if (err) goto fail;
-
-+ /* Search for sources= tag in original URL for rtp protocol only */
-+ if (strncmp(s->url, "rtp://", 6) == 0) {
-+ p = strchr(s->url, '?');
-+ if (p && av_find_info_tag(sources_buf, sizeof(sources_buf), "sources", p)) {
-+ /* av_log(s, AV_LOG_VERBOSE, "sdp_read_header found sources %s\n", sources_buf); */
-+ sp = sources_buf;
-+ sources = "&sources=";
-+ }
-+ }
-+
- /* open each RTP stream */
- for (i = 0; i < rt->nb_rtsp_streams; i++) {
- char namebuf[50];
-@@ -2432,12 +2445,22 @@ static int sdp_read_header(AVFormatContext *s)
- av_dict_free(&opts);
- goto fail;
- }
-+
-+ /* Prepare to add sources to the url to be opened.
-+ Otherwise the join to the source specific muliticast will be missing */
-+ sources2 = sources;
-+ sp2 = sp;
-+ /* ignore sources from original URL, when sources are already set in rtsp_st */
-+ if (rtsp_st->nb_include_source_addrs > 0)
-+ sources2 = sp2 = "";
-+
- ff_url_join(url, sizeof(url), "rtp", NULL,
- namebuf, rtsp_st->sdp_port,
-- "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
-+ "?localport=%d&ttl=%d&connect=%d&write_to_source=%d%s%s",
- rtsp_st->sdp_port, rtsp_st->sdp_ttl,
- rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
-- rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
-+ rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0,
-+ sources2, sp2);
-
- p = strchr(s->url, '?');
- if (p && av_find_info_tag(buf, sizeof(buf), "localaddr", p))
+++ /dev/null
---- a/libavcodec/dxva2.c
-+++ b/libavcodec/dxva2.c
-@@ -777,16 +777,18 @@
- #if CONFIG_D3D11VA
- if (avctx->pix_fmt == AV_PIX_FMT_D3D11)
- return (intptr_t)frame->data[1];
-- if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
-+ if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && surface) {
- D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
- ID3D11VideoDecoderOutputView_GetDesc((ID3D11VideoDecoderOutputView*) surface, &viewDesc);
- return viewDesc.Texture2D.ArraySlice;
- }
- #endif
- #if CONFIG_DXVA2
-- for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
-- if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
-- return i;
-+ if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
-+ for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
-+ if (ctx->dxva2.surface[i] == surface)
-+ return i;
-+ }
- }
- #endif
-
---- a/libavcodec/dxva2_h264.c
-+++ b/libavcodec/dxva2_h264.c
-@@ -507,6 +507,14 @@
-
- if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
- return -1;
-+
-+ // Wait for an I-frame before start decoding. Workaround for ATI UVD and UVD+ GPUs
-+ if (!h->got_first_iframe) {
-+ if (!(ctx_pic->pp.wBitFields & (1 << 15)))
-+ return -1;
-+ h->got_first_iframe = 1;
-+ }
-+
- ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr->f,
- &ctx_pic->pp, sizeof(ctx_pic->pp),
- &ctx_pic->qm, sizeof(ctx_pic->qm),
---- a/libavcodec/h264_slice.c
-+++ b/libavcodec/h264_slice.c
-@@ -978,6 +978,7 @@
-
- h->first_field = 0;
- h->prev_interlaced_frame = 1;
-+ h->got_first_iframe = 0;
-
- init_scan_tables(h);
- ret = ff_h264_alloc_tables(h);
---- a/libavcodec/h264dec.c
-+++ b/libavcodec/h264dec.c
-@@ -456,6 +456,7 @@
-
- h->next_outputed_poc = INT_MIN;
- h->prev_interlaced_frame = 1;
-+ h->got_first_iframe = 0;
- idr(h);
-
- h->poc.prev_frame_num = -1;
---- a/libavcodec/h264dec.h
-+++ b/libavcodec/h264dec.h
-@@ -533,6 +533,8 @@
- * slices) anymore */
- int setup_finished;
-
-+ int got_first_iframe;
-+
- int cur_chroma_format_idc;
- int cur_bit_depth_luma;
- int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
---- a/libavcodec/vaapi_h264.c
-+++ b/libavcodec/vaapi_h264.c
-@@ -314,6 +314,11 @@
- H264SliceContext *sl = &h->slice_ctx[0];
- int ret;
-
-+ if (pic->nb_slices == 0) {
-+ ret = AVERROR_INVALIDDATA;
-+ goto finish;
-+ }
-+
- ret = ff_vaapi_decode_issue(avctx, pic);
- if (ret < 0)
- goto finish;
---- a/libavformat/bintext.c
-+++ b/libavformat/bintext.c
-@@ -149,7 +149,7 @@
- return AVPROBE_SCORE_EXTENSION + 1;
-
- predict_width(&par, p->buf_size, got_width);
-- if (par.width < 8)
-+ if (par.width <= 0)
- return 0;
- calculate_height(&par, p->buf_size);
- if (par.height <= 0)
-@@ -189,8 +189,6 @@
- next_tag_read(s, &bin->fsize);
- if (!bin->width) {
- predict_width(st->codecpar, bin->fsize, got_width);
-- if (st->codecpar->width < 8)
-- return AVERROR_INVALIDDATA;
- calculate_height(st->codecpar, bin->fsize);
- }
- avio_seek(pb, 0, SEEK_SET);
+++ /dev/null
---- a/libavformat/avformat.h
-+++ b/libavformat/avformat.h
-@@ -1030,6 +1030,10 @@
- int64_t av_stream_get_end_pts(const AVStream *st);
- #endif
-
-+// Chromium: We use the internal field first_dts vvv
-+int64_t av_stream_get_first_dts(const AVStream *st);
-+// Chromium: We use the internal field first_dts ^^^
-+
- #define AV_PROGRAM_RUNNING 1
-
- /**
---- a/libavformat/utils.c
-+++ b/libavformat/utils.c
-@@ -100,6 +100,13 @@
- return pkt->size > orig_size ? pkt->size - orig_size : ret;
- }
-
-+// Chromium: We use the internal field first_dts vvv
-+int64_t av_stream_get_first_dts(const AVStream *st)
-+{
-+ return cffstream(st)->first_dts;
-+}
-+// Chromium: We use the internal field first_dts ^^^
-+
- int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
- {
- #if FF_API_INIT_PACKET
+++ /dev/null
---- a/libavformat/avio.c
-+++ b/libavformat/avio.c
-@@ -171,12 +171,12 @@
- (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value)));
- av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
- (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value)));
--
-+/*
- if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) {
- av_log(uc, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", uc->prot->name, uc->protocol_whitelist);
- return AVERROR(EINVAL);
- }
--
-+*/
- if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) {
- av_log(uc, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", uc->prot->name, uc->protocol_blacklist);
- return AVERROR(EINVAL);
+++ /dev/null
---- a/doc/demuxers.texi
-+++ b/doc/demuxers.texi
-@@ -281,7 +281,11 @@
- @table @option
-
- @item cenc_decryption_key
--16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
-+Default 16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
-+
-+ at item cenc_decryption_keys
-+Dictionary of 16-byte key ID => 16-byte key, both in hex, to decrypt files encrypted using ISO Common Encryption
-+(CENC/AES-128 CTR; ISO/IEC 23001-7).
-
- @end table
-
-@@ -769,7 +773,11 @@
- specify.
-
- @item decryption_key
--16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
-+Default 16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
-+
-+ at item decryption_keys
-+Dictionary of 16-byte key ID => 16-byte key, both in hex, to decrypt files encrypted using ISO Common Encryption
-+(CENC/AES-128 CTR; ISO/IEC 23001-7).
-
- @item max_stts_delta
- Very high sample deltas written in a trak's stts box may occasionally be intended but usually they are written in
---- a/libavformat/dashdec.c
-+++ b/libavformat/dashdec.c
-@@ -153,6 +153,7 @@
- AVDictionary *avio_opts;
- int max_url_size;
- char *cenc_decryption_key;
-+ char *cenc_decryption_keys;
-
- /* Flags for init section*/
- int is_init_section_common_video;
-@@ -1906,6 +1907,8 @@
-
- if (c->cenc_decryption_key)
- av_dict_set(&in_fmt_opts, "decryption_key", c->cenc_decryption_key, 0);
-+ if (c->cenc_decryption_keys)
-+ av_dict_set(&in_fmt_opts, "decryption_keys", c->cenc_decryption_keys, 0);
-
- // provide additional information from mpd if available
- ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts); //pls->init_section->url
-@@ -2347,7 +2350,8 @@
- OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
- {.str = "aac,m4a,m4s,m4v,mov,mp4,webm,ts"},
- INT_MIN, INT_MAX, FLAGS},
-- { "cenc_decryption_key", "Media decryption key (hex)", OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
-+ { "cenc_decryption_key", "Media default decryption key (hex)", OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
-+ { "cenc_decryption_keys", "Media decryption keys by KID (hex)", OFFSET(cenc_decryption_keys), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
- {NULL}
- };
-
---- a/libavformat/isom.h
-+++ b/libavformat/isom.h
-@@ -312,8 +312,8 @@
- void *audible_iv;
- int audible_iv_size;
- struct AVAES *aes_decrypt;
-- uint8_t *decryption_key;
-- int decryption_key_len;
-+ uint8_t *decryption_default_key;
-+ int decryption_default_key_len;
- int enable_drefs;
- int32_t movie_display_matrix[3][3]; ///< display matrix from mvhd
- int have_read_mfra_size;
-@@ -328,6 +328,7 @@
- } *avif_info;
- int avif_info_size;
- int interleaved_read;
-+ AVDictionary* decryption_keys;
- } MOVContext;
-
- int ff_mp4_read_descr_len(AVIOContext *pb);
---- a/libavformat/mov.c
-+++ b/libavformat/mov.c
-@@ -7130,19 +7130,62 @@
- return 0;
- }
-
-+static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
-+ AVDictionaryEntry *key_entry_hex;
-+ char kid_hex[16*2+1];
-+
-+ if (c->decryption_default_key && c->decryption_default_key_len != len) {
-+ av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
-+ return -1;
-+ }
-+
-+ if (!c->decryption_keys) {
-+ av_assert0(c->decryption_default_key);
-+ memcpy(out, c->decryption_default_key, len);
-+ return 0;
-+ }
-+
-+ if (sample->key_id_size != 16) {
-+ av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
-+ return -1;
-+ }
-+
-+ ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
-+ key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
-+ if (!key_entry_hex) {
-+ if (!c->decryption_default_key) {
-+ av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
-+ return -1;
-+ }
-+ memcpy(out, c->decryption_default_key, len);
-+ return 0;
-+ }
-+ if (strlen(key_entry_hex->value) != len*2) {
-+ return -1;
-+ }
-+ ff_hex_to_data(out, key_entry_hex->value);
-+ return 0;
-+}
-+
- static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
- {
- int i, ret;
- int bytes_of_protected_data;
-+ uint8_t decryption_key[AES_CTR_KEY_SIZE];
-
- if (!sc->cenc.aes_ctr) {
-+ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
-+ if (ret < 0) {
-+ return ret;
-+ }
-+
- /* 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);
-+ ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
- if (ret < 0) {
- return ret;
- }
-@@ -7188,15 +7231,21 @@
- int i, ret;
- int num_of_encrypted_blocks;
- uint8_t iv[16];
-+ uint8_t decryption_key[16];
-
- if (!sc->cenc.aes_ctx) {
-+ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
-+ if (ret < 0) {
-+ return ret;
-+ }
-+
- /* 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);
-+ ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
- if (ret < 0) {
- return ret;
- }
-@@ -7247,15 +7296,21 @@
- {
- int i, ret, rem_bytes;
- uint8_t *data;
-+ uint8_t decryption_key[AES_CTR_KEY_SIZE];
-
- if (!sc->cenc.aes_ctr) {
-+ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
-+ if (ret < 0) {
-+ return ret;
-+ }
-+
- /* 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);
-+ ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
- if (ret < 0) {
- return ret;
- }
-@@ -7313,15 +7368,21 @@
- int i, ret, rem_bytes;
- uint8_t iv[16];
- uint8_t *data;
-+ uint8_t decryption_key[16];
-
- if (!sc->cenc.aes_ctx) {
-+ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
-+ if (ret < 0) {
-+ return ret;
-+ }
-+
- /* 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);
-+ ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
- if (ret < 0) {
- return ret;
- }
-@@ -7464,7 +7525,7 @@
- return AVERROR_INVALIDDATA;
- }
-
-- if (mov->decryption_key) {
-+ if (mov->decryption_keys || mov->decryption_default_key) {
- return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
- } else {
- size_t size;
-@@ -8613,12 +8674,6 @@
- MOVAtom atom = { AV_RL32("root") };
- int i;
-
-- if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
-- av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
-- mov->decryption_key_len, AES_CTR_KEY_SIZE);
-- return AVERROR(EINVAL);
-- }
--
- mov->fc = s;
- mov->trak_index = -1;
- /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
-@@ -9317,7 +9372,8 @@
- "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
- AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
- .flags = AV_OPT_FLAG_DECODING_PARAM },
-- { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
-+ { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
-+ { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
- { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
- {.i64 = 0}, 0, 1, FLAGS },
- { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM },
---- a/tests/fate/mov.mak
-+++ b/tests/fate/mov.mak
-@@ -8,6 +8,9 @@
- fate-mov-3elist-encrypted \
- fate-mov-frag-encrypted \
- fate-mov-tenc-only-encrypted \
-+ fate-mov-3elist-encrypted-kid \
-+ fate-mov-frag-encrypted-kid \
-+ fate-mov-tenc-only-encrypted-kid \
- fate-mov-invalid-elst-entry-count \
- fate-mov-gpmf-remux \
- fate-mov-440hz-10ms \
-@@ -57,6 +60,15 @@ fate-mov-frag-encrypted: CMD = framemd5 -decryption_key 123456789012345678901234
- # Full-sample encryption and constant IV using only tenc atom (no senc/saio/saiz).
- fate-mov-tenc-only-encrypted: CMD = framemd5 -decryption_key 12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-tenc-only-encrypted.mp4
-
-+# Edit list with encryption, using the decryption_keys option.
-+fate-mov-3elist-encrypted-kid: CMD = framemd5 -decryption_keys 12345678901234567890123456789012=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-3elist-encrypted.mov
-+
-+# Fragmented encryption with senc boxes in movie fragments, using the decryption_keys option.
-+fate-mov-frag-encrypted-kid: CMD = framemd5 -decryption_keys abba271e8bcf552bbd2e86a434a9a5d9=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-frag-encrypted.mp4
-+
-+# Full-sample encryption and constant IV using only tenc atom (no senc/saio/saiz), using the decryption_keys option.
-+fate-mov-tenc-only-encrypted-kid: CMD = framemd5 -decryption_keys abba271e8bcf552bbd2e86a434a9a5d9=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-tenc-only-encrypted.mp4
-+
- # Makes sure that the CTTS is also modified when we fix avindex in mov.c while parsing edit lists.
- fate-mov-elist-starts-ctts-2ndsample: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-elist-starts-ctts-2ndsample.mov
-
---- /dev/null
-+++ b/tests/ref/fate/mov-3elist-encrypted-kid
-@@ -0,0 +1,57 @@
-+#format: frame checksums
-+#version: 2
-+#hash: MD5
-+#tb 0: 1/24
-+#media_type 0: video
-+#codec_id 0: rawvideo
-+#dimensions 0: 640x480
-+#sar 0: 0/1
-+#stream#, dts, pts, duration, size, hash
-+0, 0, 0, 1, 460800, 80fbbdec589e15e6c493b44d243f92a9
-+0, 1, 1, 1, 460800, f4b23293bb2ecf69cc3570853d8c56a1
-+0, 2, 2, 1, 460800, 0c03ce2c1c6ec405d7455465ecd559a3
-+0, 3, 3, 1, 460800, 7921791695537fba2c3c123da4834cb9
-+0, 4, 4, 1, 460800, 30c8e2903a561b84d4cbaf95c668d236
-+0, 5, 5, 1, 460800, 7ff42e998217c17592ddf6b584f26cef
-+0, 6, 6, 1, 460800, 5e402c48bf097db2d31b82bb4194a382
-+0, 7, 7, 1, 460800, 824c49e92c8ae6d99a0207b514dd756c
-+0, 8, 8, 1, 460800, 24f189216a1d9cf2313b2d6dbe3dbdd3
-+0, 9, 9, 1, 460800, 519179a8e74275d26b183374637e003f
-+0, 10, 10, 1, 460800, f18331ddcef0adf5b069bfa98baf8db4
-+0, 11, 11, 1, 460800, 081f61688690d47dbdddd5384e5d5a70
-+0, 12, 12, 1, 460800, 90dbf019b9035433371a8df41a9268b7
-+0, 13, 13, 1, 460800, bb5adfb9c66732898b34186eca1667ba
-+0, 14, 14, 1, 460800, cc08cfd64f37783ecddaf143f6ad78bc
-+0, 15, 15, 1, 460800, b8ae21d024fe4df903d56f4521993c72
-+0, 16, 16, 1, 460800, b45a99907f045dcadf0a2befc11555e3
-+0, 17, 17, 1, 460800, 603ba935845e65ab6cccbbec88bbf60d
-+0, 18, 18, 1, 460800, df80c8d3e6a77258a306903f17995a18
-+0, 19, 19, 1, 460800, 4b7e90c0a5fd0e0cd958d47f0afac636
-+0, 20, 20, 1, 460800, 9feb6e36182f1745be6387edea240eb6
-+0, 21, 21, 1, 460800, 86e6de4bd0a5ff7558f4cf6c1ec3930d
-+0, 22, 22, 1, 460800, 726b69df77edbe7b503d4698656d1320
-+0, 23, 23, 1, 460800, d282fb7a953ac205b0a43d00c2d60a33
-+0, 24, 24, 1, 460800, eece3daa70cc20208dd75d91ac84c8fd
-+0, 25, 25, 1, 460800, c86d23e73bcce351fc315fb1f13348da
-+0, 26, 26, 1, 460800, 93497b4f7c5ad9d61212239b7c9d2770
-+0, 27, 27, 1, 460800, eb217d2c12de67903835a8c58f620488
-+0, 28, 28, 1, 460800, d966480867bb54c8cd044f18388ed486
-+0, 29, 29, 1, 460800, 3ea6207942b3181fdd8e8aa6cae1062a
-+0, 30, 30, 1, 460800, 2620df54aca086ec0fb9527c6e6f5135
-+0, 31, 31, 1, 460800, 43bb7320f0bb583188dc965ddbfade90
-+0, 32, 32, 1, 460800, 0cddaa04645f804e02f65b0836412113
-+0, 33, 33, 1, 460800, 83b2dc95807289d7f4a4632bf18c2e97
-+0, 34, 34, 1, 460800, 98134d0e41e6dd12827049ccf33b4669
-+0, 35, 35, 1, 460800, 56f55631731fa39c7acbab0afeb2eb1b
-+0, 36, 36, 1, 460800, 379c1105be09d836a515dc909455ddf4
-+0, 37, 37, 1, 460800, 1df87c47e9d98731faf1c3885b77e5da
-+0, 38, 38, 1, 460800, 9a8734bcbfdb4d97e530683b8b556a26
-+0, 39, 39, 1, 460800, c7a7990d0cddc5adfbe27da7a42e025e
-+0, 40, 40, 1, 460800, 0c81e46011e03be410feaf056207fd55
-+0, 41, 41, 1, 460800, ca76e4e63016ff29d8aeeb9cb053bb6c
-+0, 42, 42, 1, 460800, cebfbe299c17c1f8fc1e6b189555c3c2
-+0, 43, 43, 1, 460800, 4f002c5feca5e75f07089e0df47507dd
-+0, 44, 44, 1, 460800, c5fd83fc4a745abee9b3d9a6eec9dd3e
-+0, 45, 45, 1, 460800, 57d9bad9b45aa2746de5d8bdc2c24969
-+0, 46, 46, 1, 460800, 9831673ad7dec167af4a959f64258949
-+0, 47, 47, 1, 460800, 77a1cb208f70f51bcb01e28d8cba73b4
---- /dev/null
-+++ b/tests/ref/fate/mov-frag-encrypted-kid
-@@ -0,0 +1,57 @@
-+#format: frame checksums
-+#version: 2
-+#hash: MD5
-+#tb 0: 1/24
-+#media_type 0: video
-+#codec_id 0: rawvideo
-+#dimensions 0: 120x52
-+#sar 0: 544/545
-+#stream#, dts, pts, duration, size, hash
-+0, 0, 0, 1, 9360, 920bdc277a6a31c1daed9aca44b10caf
-+0, 1, 1, 1, 9360, f1c0b61fef593de57cb97be7fa846569
-+0, 2, 2, 1, 9360, 6ef32d9d4398355aebf6d3fb11d51d3f
-+0, 3, 3, 1, 9360, d38fd3ef1e5a92fc109b8dd9eb6dadeb
-+0, 4, 4, 1, 9360, 54cc0c8a25d2f14f32663837d5e646f1
-+0, 5, 5, 1, 9360, b4b6829726dc3decb8b80ba0c35bcf30
-+0, 6, 6, 1, 9360, fca3f941e60a2f0a4ce30d5e0efbec3c
-+0, 7, 7, 1, 9360, cda6e26b6c1039ff3d229b262c9210c3
-+0, 8, 8, 1, 9360, f0d69255e3a27a8b4ae8a4b7b210929d
-+0, 9, 9, 1, 9360, 12cb23dd4e32af9c3b35f943714e3fdd
-+0, 10, 10, 1, 9360, 082aaf3216124ddcecb422fe5c832e82
-+0, 11, 11, 1, 9360, ff37bb8cd6bd0412a3b3cb45db54afc9
-+0, 12, 12, 1, 9360, dfb9085441575732844b6c2f05d5f542
-+0, 13, 13, 1, 9360, 0017100feaaa9fc7eacd2447d50d7542
-+0, 14, 14, 1, 9360, 4e2f1b8c4e04c59934c2f58541e62613
-+0, 15, 15, 1, 9360, 27a44dfea7cd2d30e488194c34ab473c
-+0, 16, 16, 1, 9360, fc7b56bd95e990a33cf575d1ef820902
-+0, 17, 17, 1, 9360, fa2d1609e69714dffc410e65f3c8b755
-+0, 18, 18, 1, 9360, 705d7429f447cb13febe202d567795f2
-+0, 19, 19, 1, 9360, 234802ce86e868faaf2cd40a286846ea
-+0, 20, 20, 1, 9360, 2f0354b40d211d0a4ade4568bea4f85e
-+0, 21, 21, 1, 9360, e96af3b6c0cc931463ca77d6be0f1148
-+0, 22, 22, 1, 9360, 04a904d798361959971361401879c7e4
-+0, 23, 23, 1, 9360, 2f119642340df6d25362b5590ded46b7
-+0, 24, 24, 1, 9360, 5993fca2e60050706f857ac76e48f386
-+0, 25, 25, 1, 9360, 2ff3b5775fed3d527bfbbeea786787fe
-+0, 26, 26, 1, 9360, 42024dbe23d3fb5b0d8987ae1ce390a8
-+0, 27, 27, 1, 9360, d804204f0bd9db5f6a758e2c934d9e38
-+0, 28, 28, 1, 9360, e322712e6e34c58ec1a2ab5e2c1e3bfe
-+0, 29, 29, 1, 9360, 3975bd1a5f6a6b6260276777f9de611e
-+0, 30, 30, 1, 9360, 4388f0412efc6310706a7cdedc859ea9
-+0, 31, 31, 1, 9360, b4b9a11b0b86635267345a569640e8d4
-+0, 32, 32, 1, 9360, 31879c7b8d6b67a4209ffde786bb8cb4
-+0, 33, 33, 1, 9360, 4b6dc02d7c889fe4abd4e013b25f585a
-+0, 34, 34, 1, 9360, dc73aae82bd39a1220d1106c8d3e8252
-+0, 35, 35, 1, 9360, 54c7dfbd49f312806f6c1a89f7c2c36f
-+0, 36, 36, 1, 9360, 150abc64f8994d444a521ea90570443c
-+0, 37, 37, 1, 9360, d277cdc7dcadbe0016f2e950459e7ebf
-+0, 38, 38, 1, 9360, 2196bf338ead90ea54687b85c73c8229
-+0, 39, 39, 1, 9360, 53ce5da5365abc0bd3217dd98e7c465d
-+0, 40, 40, 1, 9360, 34ee9832aea55c0c4e6f4381c413c10e
-+0, 41, 41, 1, 9360, 1769c7b5849e4681119067a06ac29a4f
-+0, 42, 42, 1, 9360, 71f53df739ef283a5184c91ef4b158e8
-+0, 43, 43, 1, 9360, d2d394739e9a59c06f0354c16843cb63
-+0, 44, 44, 1, 9360, d8e458e92ae29344505a24a3059fc584
-+0, 45, 45, 1, 9360, 0f1b11a09911851b798df2ef76253a7f
-+0, 46, 46, 1, 9360, 5c4a9f22baecf4e749c0d5c65a4f1007
-+0, 47, 47, 1, 9360, 3e2b7e7262fdca08d9d1ef6070125c4b
---- /dev/null
-+++ b/tests/ref/fate/mov-tenc-only-encrypted-kid
-@@ -0,0 +1,57 @@
-+#format: frame checksums
-+#version: 2
-+#hash: MD5
-+#tb 0: 1/24
-+#media_type 0: video
-+#codec_id 0: rawvideo
-+#dimensions 0: 1024x436
-+#sar 0: 1/1
-+#stream#, dts, pts, duration, size, hash
-+0, 0, 0, 1, 669696, f48f296a85eda5ba069dc851a3228bef
-+0, 1, 1, 1, 669696, a50c5f69bfa3387d49b5bdf738e6529c
-+0, 2, 2, 1, 669696, 05061299003760f6a4795b408f72aa31
-+0, 3, 3, 1, 669696, 2572119f0b0cdd83f8a7e06252cecd3b
-+0, 4, 4, 1, 669696, 29fe6a6bdb4a69018e318886a297f07e
-+0, 5, 5, 1, 669696, e8233c7fbaecfbff965c7dfdd3982b1b
-+0, 6, 6, 1, 669696, d9259df9880ff5d4a4b38282e67f407b
-+0, 7, 7, 1, 669696, 3e8d795195038993503ea9ab6984c915
-+0, 8, 8, 1, 669696, bc4e2d253b715a34f85aae1b080e3460
-+0, 9, 9, 1, 669696, 09aba8b3a96f53f9268e7420a10bfab6
-+0, 10, 10, 1, 669696, 179447977dd580da8b35fb5310a809ca
-+0, 11, 11, 1, 669696, 7a0eea9d54577990345f5705ab9882be
-+0, 12, 12, 1, 669696, 5bb96eb76f461825740e5938456df759
-+0, 13, 13, 1, 669696, bd4ac4a760ead774b9422a27dc071964
-+0, 14, 14, 1, 669696, 1cc05f760a9b751fc89e77f2bcc97259
-+0, 15, 15, 1, 669696, 825d0dee6f0174ba7102892c7de30b4d
-+0, 16, 16, 1, 669696, d26a2ef5267f6bb03c4e1d8514eee0df
-+0, 17, 17, 1, 669696, c916ffdeadca76596a8f7fd47914b5ef
-+0, 18, 18, 1, 669696, 6e085acfa7fee0658ea0ae6188274c17
-+0, 19, 19, 1, 669696, 1e95fa5b3561283f05bf0bd44cb91721
-+0, 20, 20, 1, 669696, 37e3d135aba9dfb8b87e441753115374
-+0, 21, 21, 1, 669696, 9c398310e8564491de624393c16265ce
-+0, 22, 22, 1, 669696, c87209e4d2617bc2ab40a75f455f09da
-+0, 23, 23, 1, 669696, 2679c2f8d1d1af21982e245945c1ee60
-+0, 24, 24, 1, 669696, 6151ab4781f31c5beb66b356ad547122
-+0, 25, 25, 1, 669696, f7ef6293bfb3a6a329061cb6a5ed5a38
-+0, 26, 26, 1, 669696, 2f6e666d14dfc407ca0c0f347b13eb08
-+0, 27, 27, 1, 669696, 3454fa1730d79b1aa8dbbc865dc150f4
-+0, 28, 28, 1, 669696, e93dc683e2453419a0419ab9af0f8f95
-+0, 29, 29, 1, 669696, 031eb3154f7f83cf86d42bee66be9cf7
-+0, 30, 30, 1, 669696, 1205c36723e88811206c68892d3aaed6
-+0, 31, 31, 1, 669696, 7dd7a8a19dcd73b31ddc6a6d0c597a42
-+0, 32, 32, 1, 669696, 7c91115368ea2531262a1197468bc3f4
-+0, 33, 33, 1, 669696, 3cf6d9ba385e0fff76da33299ed5380c
-+0, 34, 34, 1, 669696, 859fc8c3ef049e3c1175a85fb0a90a3d
-+0, 35, 35, 1, 669696, 1d09ce6c7027103d99a4d5799f6e72ab
-+0, 36, 36, 1, 669696, 3dcb8357408ac88abd734128d8f5dd6f
-+0, 37, 37, 1, 669696, 4dafce137a0a5178f6efaec878e64d36
-+0, 38, 38, 1, 669696, 44c478f29a1399ed03275a7357f57d48
-+0, 39, 39, 1, 669696, 6e9edaac7414c0e14591ac3d4d0b1ac4
-+0, 40, 40, 1, 669696, 522e4aaeea0825da27f631a9e690d654
-+0, 41, 41, 1, 669696, 85f2502a718440834c40051d30f8a65e
-+0, 42, 42, 1, 669696, ae8816f7bd4645ef1a17ee6d09b4c8d2
-+0, 43, 43, 1, 669696, 914b006fa92f1eb3e590245749f6810d
-+0, 44, 44, 1, 669696, 9406901542e94c429dff46108782ed69
-+0, 45, 45, 1, 669696, 324c13641c39eef5c476023e358c0391
-+0, 46, 46, 1, 669696, 4058e886e17c22e4eb9da1dd0d6ad891
-+0, 47, 47, 1, 669696, 9edf9cd15eea985b42fd1f5035b1d693
---
+++ /dev/null
-diff --git a/libavutil/common.h b/libavutil/common.h
-index fd1404be6c..0bb8650e83 100644
---- a/libavutil/common.h
-+++ b/libavutil/common.h
-@@ -351,7 +351,8 @@ static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) {
- return !__builtin_add_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN);
- #else
- int64_t s = a+(uint64_t)b;
-- if ((int64_t)(a^b | ~s^b) >= 0)
-+ // PATCH: GCC 4.9.4 complains about missing parentheses when combining bitwise operations.
-+ if ((int64_t)((a^b) | (~s^b)) >= 0)
- return INT64_MAX ^ (b >> 63);
- return s;
- #endif
+++ /dev/null
-diff --git a/libavcodec/Makefile b/libavcodec/Makefile
-index 457ec58377..49bf260764 100644
---- a/libavcodec/Makefile
-+++ b/libavcodec/Makefile
-@@ -1209,6 +1209,8 @@ OBJS-$(CONFIG_SETTS_BSF) += setts_bsf.o
- OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o
- OBJS-$(CONFIG_TRACE_HEADERS_BSF) += trace_headers_bsf.o
- OBJS-$(CONFIG_TRUEHD_CORE_BSF) += truehd_core_bsf.o mlp_parse.o mlp.o
-+OBJS-$(CONFIG_VC1_ASFTORCV_BSF) += vc1_asftorcv_bsf.o
-+OBJS-$(CONFIG_VC1_ASFTOANNEXG_BSF) += vc1_asftoannexg_bsf.o vc1.o
- OBJS-$(CONFIG_VP9_METADATA_BSF) += vp9_metadata_bsf.o
- OBJS-$(CONFIG_VP9_RAW_REORDER_BSF) += vp9_raw_reorder_bsf.o
- OBJS-$(CONFIG_VP9_SUPERFRAME_BSF) += vp9_superframe_bsf.o
-diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
-index 444423ae93..482d3473b2 100644
---- a/libavcodec/bitstream_filters.c
-+++ b/libavcodec/bitstream_filters.c
-@@ -59,6 +59,8 @@ extern const FFBitStreamFilter ff_setts_bsf;
- extern const FFBitStreamFilter ff_text2movsub_bsf;
- extern const FFBitStreamFilter ff_trace_headers_bsf;
- extern const FFBitStreamFilter ff_truehd_core_bsf;
-+extern const FFBitStreamFilter ff_vc1_asftoannexg_bsf;
-+extern const FFBitStreamFilter ff_vc1_asftorcv_bsf;
- extern const FFBitStreamFilter ff_vp9_metadata_bsf;
- extern const FFBitStreamFilter ff_vp9_raw_reorder_bsf;
- extern const FFBitStreamFilter ff_vp9_superframe_bsf;
-diff --git a/libavcodec/vc1_asftoannexg_bsf.c b/libavcodec/vc1_asftoannexg_bsf.c
-new file mode 100644
-index 0000000000..2901f84d9c
---- /dev/null
-+++ b/libavcodec/vc1_asftoannexg_bsf.c
-@@ -0,0 +1,190 @@
-+/*
-+ * copyright (c) 2010 Google Inc.
-+ * copyright (c) 2013 CoolStream International Ltd.
-+ * copyright (c) 2017 Jacek Jendrzej port to 3.x
-+ * This file is part of FFmpeg.
-+ *
-+ * FFmpeg is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * FFmpeg is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with FFmpeg; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-+ */
-+
-+#include "avcodec.h"
-+#include "bytestream.h"
-+#include "vc1.h"
-+#include "bsf.h"
-+#include "bsf_internal.h"
-+
-+// An arbitrary limit in bytes greater than the current bytes used.
-+#define MAX_SEQ_HEADER_SIZE 50
-+
-+typedef struct ASFTOANNEXGBSFContext {
-+ int frames;
-+ uint8_t *seq_header;
-+ int seq_header_size;
-+ uint8_t *ep_header;
-+ int ep_header_size;
-+} ASFTOANNEXGBSFContext;
-+
-+static int find_codec_data(ASFTOANNEXGBSFContext *ctx, uint8_t *data, int data_size, int keyframe) {
-+ const uint8_t *start = data;
-+ const uint8_t *end = data + data_size;
-+ const uint8_t *next;
-+ int size;
-+ int has_seq_header = 0;
-+ int has_ep_header = 0;
-+ int has_frame_header = 0;
-+
-+ start = find_next_marker(start, end);
-+ next = start;
-+ for(; next < end; start = next){
-+ next = find_next_marker(start + 4, end);
-+ size = next - start;
-+ if(size <= 0) continue;
-+ switch(AV_RB32(start)){
-+ case VC1_CODE_SEQHDR:
-+ has_seq_header = 1;
-+ break;
-+ case VC1_CODE_ENTRYPOINT:
-+ has_ep_header = 1;
-+ break;
-+ case VC1_CODE_FRAME:
-+ has_frame_header = 1;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ if((has_seq_header && has_ep_header && has_frame_header && keyframe) ||
-+ (!has_seq_header && !has_ep_header && has_frame_header) ) return 0;
-+
-+ return -1;
-+}
-+
-+static int parse_extradata(ASFTOANNEXGBSFContext *ctx, uint8_t *extradata, int extradata_size) {
-+ const uint8_t *start = extradata;
-+ const uint8_t *end = extradata + extradata_size;
-+ const uint8_t *next;
-+ int size;
-+
-+ start = find_next_marker(start, end);
-+ next = start;
-+ for(; next < end; start = next){
-+ next = find_next_marker(start + 4, end);
-+ size = next - start;
-+ if(size <= 0) continue;
-+ switch(AV_RB32(start)){
-+ case VC1_CODE_SEQHDR:
-+ ctx->seq_header = av_mallocz(size);
-+ ctx->seq_header_size = size;
-+ memcpy(ctx->seq_header, start, size);
-+ break;
-+ case VC1_CODE_ENTRYPOINT:
-+ ctx->ep_header = av_malloc(size);
-+ ctx->ep_header_size = size;
-+ memcpy(ctx->ep_header, start, size);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ if(!ctx->seq_header || !ctx->ep_header) {
-+ av_log(NULL, AV_LOG_ERROR, "Incomplete extradata\n");
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static int asftoannexg_filter(AVBSFContext *ctx, AVPacket *out)
-+{
-+ ASFTOANNEXGBSFContext* bsfctx = ctx->priv_data;
-+ AVPacket *in;
-+ int keyframe;
-+ int ret;
-+ uint8_t* bs = NULL;
-+
-+ ret = ff_bsf_get_packet(ctx, &in);
-+ if (ret < 0)
-+ return ret;
-+
-+ keyframe = in->flags & AV_PKT_FLAG_KEY;
-+ if(in->size >= 1 && !find_codec_data(bsfctx, in->data, in->size, keyframe)) {
-+// av_log(NULL, AV_LOG_INFO, "Nothing to do: %i\n",in->size);
-+ av_packet_move_ref(out, in);
-+ av_packet_free(&in);
-+ return 0;
-+ }
-+
-+ if(!ctx->par_in->extradata || ctx->par_in->extradata_size < 16) {
-+ av_log(NULL, AV_LOG_INFO, "Extradata size too small: %i\n", ctx->par_in->extradata_size);
-+ av_packet_move_ref(out, in);
-+ av_packet_free(&in);
-+ return 0;
-+ }
-+
-+ if (!bsfctx->frames && parse_extradata(bsfctx, ctx->par_in->extradata , ctx->par_in->extradata_size) < 0) {
-+ av_packet_free(&in);
-+ av_log(NULL, AV_LOG_ERROR, "Cannot parse extra data!\n");
-+ return -1;
-+ }
-+
-+ if (keyframe) {
-+ // If this is the keyframe, need to put sequence header and entry point header.
-+ ret = av_new_packet(out, bsfctx->seq_header_size + bsfctx->ep_header_size + 4 + in->size);
-+ if (ret < 0)
-+ goto exit;
-+ bs = out->data;
-+
-+ memcpy(bs, bsfctx->seq_header, bsfctx->seq_header_size);
-+ bs += bsfctx->seq_header_size;
-+ memcpy(bs, bsfctx->ep_header, bsfctx->ep_header_size);
-+ bs += bsfctx->ep_header_size;
-+ } else {
-+ ret = av_new_packet(out, 4 + in->size);
-+ if (ret < 0)
-+ goto exit;
-+ bs = out->data;
-+ }
-+
-+ // Put the frame start code and frame data.
-+ bytestream_put_be32(&bs, VC1_CODE_FRAME);
-+ memcpy(bs, in->data, in->size);
-+ ++bsfctx->frames;
-+
-+ ret = av_packet_copy_props(out, in);
-+
-+exit:
-+ av_packet_free(&in);
-+
-+ return ret;
-+}
-+
-+static void asftoannexg_close(AVBSFContext *bsfc) {
-+ ASFTOANNEXGBSFContext *bsfctx = bsfc->priv_data;
-+ av_freep(&bsfctx->seq_header);
-+ av_freep(&bsfctx->ep_header);
-+}
-+
-+static const enum AVCodecID codec_ids[] = {
-+ AV_CODEC_ID_VC1, AV_CODEC_ID_NONE,
-+};
-+
-+FFBitStreamFilter ff_vc1_asftoannexg_bsf = {
-+ .p.name = "vc1_asftoannexg",
-+ .priv_data_size = sizeof(ASFTOANNEXGBSFContext),
-+ .filter = asftoannexg_filter,
-+ .close = asftoannexg_close,
-+ .p.codec_ids = codec_ids,
-+};
-diff --git a/libavcodec/vc1_asftorcv_bsf.c b/libavcodec/vc1_asftorcv_bsf.c
-new file mode 100644
-index 0000000000..02e510b4b6
---- /dev/null
-+++ b/libavcodec/vc1_asftorcv_bsf.c
-@@ -0,0 +1,105 @@
-+/*
-+ * copyright (c) 2010 Google Inc.
-+ * copyright (c) 2017 Jacek Jendrzej port to 3.x
-+ * This file is part of FFmpeg.
-+ *
-+ * FFmpeg is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * FFmpeg is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with FFmpeg; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-+ */
-+
-+#include "avcodec.h"
-+#include "bytestream.h"
-+#include "bsf.h"
-+#include "bsf_internal.h"
-+
-+#define RCV_STREAM_HEADER_SIZE 36
-+#define RCV_PICTURE_HEADER_SIZE 8
-+
-+typedef struct ASFTORCVBSFContext {
-+ int frames;
-+} ASFTORCVBSFContext;
-+
-+static int asftorcv_filter(AVBSFContext *ctx, AVPacket *out){
-+ ASFTORCVBSFContext* bsfctx = ctx->priv_data;
-+ AVPacket *in;
-+ int keyframe;
-+ int ret;
-+ uint8_t* bs = NULL;
-+
-+ ret = ff_bsf_get_packet(ctx, &in);
-+ if (ret < 0)
-+ return ret;
-+
-+ keyframe = in->flags & AV_PKT_FLAG_KEY;
-+
-+ if (!bsfctx->frames) {
-+ // Write the header if this is the first frame.
-+ ret = av_new_packet(out, RCV_STREAM_HEADER_SIZE + RCV_PICTURE_HEADER_SIZE + in->size);
-+ if (ret < 0)
-+ goto exit;
-+ bs = out->data;
-+
-+ // The following structure of stream header comes from libavformat/vc1testenc.c.
-+ bytestream_put_le24(&bs, 0); // Frame count. 0 for streaming.
-+ bytestream_put_byte(&bs, 0xC5);
-+ bytestream_put_le32(&bs, 4); // 4 bytes of extra data.
-+ bytestream_put_byte(&bs, ctx->par_in->extradata[0]);
-+ bytestream_put_byte(&bs, ctx->par_in->extradata[1]);
-+ bytestream_put_byte(&bs, ctx->par_in->extradata[2]);
-+ bytestream_put_byte(&bs, ctx->par_in->extradata[3]);
-+ bytestream_put_le32(&bs, ctx->par_in->height);
-+ bytestream_put_le32(&bs, ctx->par_in->width);
-+ bytestream_put_le32(&bs, 0xC);
-+ bytestream_put_le24(&bs, 0); // hrd_buffer
-+ bytestream_put_byte(&bs, 0x80); // level|cbr|res1
-+ bytestream_put_le32(&bs, 0); // hrd_rate
-+
-+ // The following LE32 describes the frame rate. Since we don't care so fill
-+ // it with 0xFFFFFFFF which means variable framerate.
-+ // See: libavformat/vc1testenc.c
-+ bytestream_put_le32(&bs, 0xFFFFFFFF);
-+ } else {
-+ ret = av_new_packet(out, RCV_PICTURE_HEADER_SIZE + in->size);
-+ if (ret < 0)
-+ goto exit;
-+ bs = out->data;
-+ }
-+
-+ // Write the picture header.
-+ bytestream_put_le32(&bs, in->size | (keyframe ? 0x80000000 : 0));
-+
-+ // The following LE32 describes the pts. Since we don't care so fill it with 0.
-+ bytestream_put_le32(&bs, 0);
-+ memcpy(bs, in->data, in->size);
-+
-+ ++bsfctx->frames;
-+
-+ ret = av_packet_copy_props(out, in);
-+
-+exit:
-+ av_packet_free(&in);
-+
-+ return ret;
-+}
-+
-+static const enum AVCodecID codec_ids[] = {
-+ AV_CODEC_ID_WMV3, AV_CODEC_ID_NONE,
-+};
-+
-+FFBitStreamFilter ff_vc1_asftorcv_bsf = {
-+ .p.name = "vc1_asftorcv",
-+ .priv_data_size = sizeof(ASFTORCVBSFContext),
-+ .filter = asftorcv_filter,
-+ .p.codec_ids = codec_ids,
-+};
+++ /dev/null
-# Test case: The.Purge.2013.1080p.BluRay.x264.YIFY.mp4
-From 1c7b83f945e710a17a41ad9feb7dc929f26f2b0e Mon Sep 17 00:00:00 2001
-From: Jacek Jendrzej <satbaby@kawaii.com>
-Date: Wed, 28 Jun 2017 11:38:20 +0200
-Subject: [PATCH] fix sps/pps for cooli;This is commit that breaks seek in some
- mkv.break with commit 6d2219e9f950b96279fd8464cc11c4d02518b629
-
----
- libavcodec/h264_mp4toannexb_bsf.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
-index 2822644b10..d57647d25c 100644
---- a/libavcodec/h264_mp4toannexb_bsf.c
-+++ b/libavcodec/h264_mp4toannexb_bsf.c
-@@ -242,6 +242,11 @@ static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *opkt)
- if (!new_idr && unit_type == H264_NAL_IDR_SLICE && (buf[1] & 0x80))
- new_idr = 1;
-
-+ if (s->new_idr && unit_type == H264_NAL_SEI && s->idr_sps_seen && s->idr_pps_seen) {
-+ s->idr_sps_seen = 0;
-+ s->idr_pps_seen = 0;
-+ }
-+
- /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */
- if (new_idr && unit_type == H264_NAL_IDR_SLICE && !sps_seen && !pps_seen) {
- if (ctx->par_out->extradata)
--- /dev/null
+diff --git a/libavutil/log.c b/libavutil/log.c
+index 5948e50467..528eaa728c 100644
+--- a/libavutil/log.c
++++ b/libavutil/log.c
+@@ -53,7 +53,7 @@ static AVMutex mutex = AV_MUTEX_INITIALIZER;
+ #define BACKTRACE_LOGLEVEL AV_LOG_ERROR
+ #endif
+
+-static int av_log_level = AV_LOG_INFO;
++static int av_log_level = AV_LOG_ERROR; // NOT WORKING for libs
+ static int flags;
+
+ #define NB_LEVELS 8
+@@ -408,10 +408,6 @@ static void (*av_log_callback)(void*, int, const char*, va_list) =
+
+ void av_log(void* avcl, int level, const char *fmt, ...)
+ {
+- va_list vl;
+- va_start(vl, fmt);
+- av_vlog(avcl, level, fmt, vl);
+- va_end(vl);
+ }
+
+ void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...)
--- /dev/null
+--- a/libavformat/mpegts.c
++++ b/libavformat/mpegts.c
+@@ -1041,10 +1041,12 @@
+ pes->buffer = NULL;
+ reset_pes_packet_state(pes);
+
++ /*
+ sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
+ if (!sd)
+ return AVERROR(ENOMEM);
+ *sd = pes->stream_id;
++ */
+
+ return 0;
+ }
--- /dev/null
+--- a/configure
++++ b/configure
+@@ -3615,10 +3615,8 @@
+ # protocols
+ async_protocol_deps="threads"
+ bluray_protocol_deps="libbluray"
+-ffrtmpcrypt_protocol_conflict="librtmp_protocol"
+ ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl mbedtls"
+ ffrtmpcrypt_protocol_select="tcp_protocol"
+-ffrtmphttp_protocol_conflict="librtmp_protocol"
+ ffrtmphttp_protocol_select="http_protocol"
+ ftp_protocol_select="tcp_protocol"
+ gopher_protocol_select="tcp_protocol"
+@@ -3632,20 +3630,18 @@
+ icecast_protocol_select="http_protocol"
+ mmsh_protocol_select="http_protocol"
+ mmst_protocol_select="network"
+-rtmp_protocol_conflict="librtmp_protocol"
+-rtmp_protocol_select="tcp_protocol"
+-rtmp_protocol_suggest="zlib"
+-rtmpe_protocol_select="ffrtmpcrypt_protocol"
+-rtmpe_protocol_suggest="zlib"
+-rtmps_protocol_conflict="librtmp_protocol"
+-rtmps_protocol_select="tls_protocol"
+-rtmps_protocol_suggest="zlib"
+-rtmpt_protocol_select="ffrtmphttp_protocol"
+-rtmpt_protocol_suggest="zlib"
+-rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
+-rtmpte_protocol_suggest="zlib"
+-rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
+-rtmpts_protocol_suggest="zlib"
++ffrtmp_protocol_select="tcp_protocol"
++ffrtmp_protocol_suggest="zlib"
++ffrtmpe_protocol_select="ffrtmpcrypt_protocol"
++ffrtmpe_protocol_suggest="zlib"
++ffrtmps_protocol_select="tls_protocol"
++ffrtmps_protocol_suggest="zlib"
++ffrtmpt_protocol_select="ffrtmphttp_protocol"
++ffrtmpt_protocol_suggest="zlib"
++ffrtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
++ffrtmpte_protocol_suggest="zlib"
++ffrtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
++ffrtmpts_protocol_suggest="zlib"
+ rtp_protocol_select="udp_protocol"
+ schannel_conflict="openssl gnutls libtls mbedtls"
+ sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags"
+--- a/libavformat/Makefile
++++ b/libavformat/Makefile
+@@ -676,12 +676,12 @@
+ OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf_tags.o
+ OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+ OBJS-$(CONFIG_PROMPEG_PROTOCOL) += prompeg.o
+-OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPT_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
+ OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o ip.o
+ OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o
+ OBJS-$(CONFIG_SRTP_PROTOCOL) += srtpproto.o srtp.o
+--- a/libavformat/protocols.c
++++ b/libavformat/protocols.c
+@@ -48,12 +48,12 @@
+ extern const URLProtocol ff_md5_protocol;
+ extern const URLProtocol ff_pipe_protocol;
+ extern const URLProtocol ff_prompeg_protocol;
+-extern const URLProtocol ff_rtmp_protocol;
+-extern const URLProtocol ff_rtmpe_protocol;
+-extern const URLProtocol ff_rtmps_protocol;
+-extern const URLProtocol ff_rtmpt_protocol;
+-extern const URLProtocol ff_rtmpte_protocol;
+-extern const URLProtocol ff_rtmpts_protocol;
++extern const URLProtocol ff_ffrtmp_protocol;
++extern const URLProtocol ff_ffrtmpe_protocol;
++extern const URLProtocol ff_ffrtmps_protocol;
++extern const URLProtocol ff_ffrtmpt_protocol;
++extern const URLProtocol ff_ffrtmpte_protocol;
++extern const URLProtocol ff_ffrtmpts_protocol;
+ extern const URLProtocol ff_rtp_protocol;
+ extern const URLProtocol ff_sctp_protocol;
+ extern const URLProtocol ff_srtp_protocol;
+--- a/libavformat/rtmpproto.c
++++ b/libavformat/rtmpproto.c
+@@ -2627,7 +2627,7 @@
+ static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)
+ {
+ RTMPContext *rt = s->priv_data;
+- char proto[8], hostname[256], path[1024], auth[100], *fname;
++ char *proto, tmpProto[10], hostname[256], path[1024], auth[100], *fname;
+ char *old_app, *qmark, *n, fname_buffer[1024];
+ uint8_t buf[2048];
+ int port;
+@@ -2638,7 +2638,9 @@
+
+ rt->is_input = !(flags & AVIO_FLAG_WRITE);
+
+- av_url_split(proto, sizeof(proto), auth, sizeof(auth),
++ memset(tmpProto, 0, sizeof(tmpProto));
++ proto = &tmpProto[2];
++ av_url_split(tmpProto, sizeof(tmpProto), auth, sizeof(auth),
+ hostname, sizeof(hostname), &port,
+ path, sizeof(path), s->filename);
+
+@@ -3185,9 +3187,9 @@
+ #define RTMP_PROTOCOL(flavor, uppercase) \
+ RTMP_PROTOCOL_3(flavor, CONFIG_ ## uppercase ## _PROTOCOL)
+
+-RTMP_PROTOCOL(rtmp, RTMP)
+-RTMP_PROTOCOL(rtmpe, RTMPE)
+-RTMP_PROTOCOL(rtmps, RTMPS)
+-RTMP_PROTOCOL(rtmpt, RTMPT)
+-RTMP_PROTOCOL(rtmpte, RTMPTE)
+-RTMP_PROTOCOL(rtmpts, RTMPTS)
++RTMP_PROTOCOL(ffrtmp, FFRTMP)
++RTMP_PROTOCOL(ffrtmpe, FFRTMPE)
++RTMP_PROTOCOL(ffrtmps, FFRTMPS)
++RTMP_PROTOCOL(ffrtmpt, FFRTMPT)
++RTMP_PROTOCOL(ffrtmpte, FFRTMPTE)
++RTMP_PROTOCOL(ffrtmpts, FFRTMPTS)
--- /dev/null
+--- a/libavformat/hls.c
++++ b/libavformat/hls.c
+@@ -226,6 +226,8 @@
+ int http_persistent;
+ int http_multiple;
+ int http_seekable;
++ char *key_uri_replace_old;
++ char *key_uri_replace_new;
+ int seg_max_retry;
+ AVIOContext *playlist_pb;
+ HLSCryptoContext crypto_ctx;
+@@ -1295,8 +1297,16 @@
+
+ if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) {
+ if (strcmp(seg->key, pls->key_url)) {
++ char *key_url = NULL;
+ AVIOContext *pb = NULL;
+- if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) {
++ if (NULL != c->key_uri_replace_old && \
++ NULL != c-> key_uri_replace_new && \
++ '\0' != c->key_uri_replace_old[0]) {
++ key_url = av_strireplace(seg->key, c->key_uri_replace_old, c->key_uri_replace_new);
++ } else {
++ key_url = seg->key;
++ }
++ if (open_url(pls->parent, &pb, key_url, &c->avio_opts, opts, NULL) == 0) {
+ ret = avio_read(pb, pls->key, sizeof(pls->key));
+ if (ret != sizeof(pls->key)) {
+ av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s\n",
+@@ -1308,6 +1318,8 @@
+ seg->key);
+ }
+ av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
++ if (key_url != seg->key)
++ av_free(key_url);
+ }
+ }
+
+@@ -2579,6 +2591,8 @@
+ OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
+ {"seg_max_retry", "Maximum number of times to reload a segment on error.",
+ OFFSET(seg_max_retry), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
++ { "key_uri_old", "allow to replace part of AES key uri - old", OFFSET(key_uri_replace_old), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
++ { "key_uri_new", "allow to replace part of AES key uri - new", OFFSET(key_uri_replace_new), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
+ {NULL}
+ };
+
--- /dev/null
+--- a/configure
++++ b/configure
+@@ -6132,17 +6132,10 @@
+
+ # Check toolchain ISA level
+ if enabled mips64; then
+- enabled mips64r6 && check_inline_asm mips64r6 '"dlsa $0, $0, $0, 1"' &&
+- disable mips64r2
+-
+ enabled mips64r2 && check_inline_asm mips64r2 '"dext $0, $0, 0, 1"'
+
+ disable mips32r6 && disable mips32r5 && disable mips32r2
+ else
+- enabled mips32r6 && check_inline_asm mips32r6 '"aui $0, $0, 0"' &&
+- disable mips32r5 && disable mips32r2
+-
+- enabled mips32r5 && check_inline_asm mips32r5 '"eretnc"'
+ enabled mips32r2 && check_inline_asm mips32r2 '"ext $0, $0, 0, 1"'
+
+ disable mips64r6 && disable mips64r5 && disable mips64r2
--- /dev/null
+--- a/libavcodec/aacdec_template.c
++++ b/libavcodec/aacdec_template.c
+@@ -2520,7 +2520,7 @@
+ * @param decode 1 if tool is used normally, 0 if tool is used in LTP.
+ * @param coef spectral coefficients
+ */
+-static void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
++static __attribute__((optimize(0))) void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
+ IndividualChannelStream *ics, int decode)
+ {
+ const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
+--- a/libavcodec/aacps.c
++++ b/libavcodec/aacps.c
+@@ -397,7 +397,7 @@ static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
+ par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
+ }
+
+-static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
++static void __attribute__((optimize(0))) decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
+ {
+ LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
+ LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
--- /dev/null
+--- a/libavformat/aviobuf.c
++++ b/libavformat/aviobuf.c
+@@ -34,7 +34,7 @@
+ #include "url.h"
+ #include <stdarg.h>
+
+-#define IO_BUFFER_SIZE 32768
++#define IO_BUFFER_SIZE 262144
+
+ /**
+ * Do seeks within this distance ahead of the current buffer by skipping
+@@ -580,16 +580,15 @@
+ }
+
+ /* make buffer smaller in case it ended up large after probing */
+- if (s->read_packet && ctx->orig_buffer_size &&
+- s->buffer_size > ctx->orig_buffer_size && len >= ctx->orig_buffer_size) {
++ if (s->read_packet && s->buffer_size > max_buffer_size) {
+ if (dst == s->buffer && s->buf_ptr != dst) {
+- int ret = set_buf_size(s, ctx->orig_buffer_size);
++ int ret = set_buf_size(s, max_buffer_size);
+ if (ret < 0)
+ av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
+
+ s->checksum_ptr = dst = s->buffer;
+ }
+- len = ctx->orig_buffer_size;
++ len = max_buffer_size;
+ }
+
+ len = read_packet_wrapper(s, dst, len);
--- /dev/null
+--- a/libavformat/hls.c
++++ b/libavformat/hls.c
+@@ -2298,8 +2298,10 @@
+ HLSContext *c = s->priv_data;
+ int ret, i, minplaylist = -1;
+
+- recheck_discard_flags(s, c->first_packet);
+- c->first_packet = 0;
++ if (c->first_packet) {
++ recheck_discard_flags(s, 1);
++ c->first_packet = 0;
++ }
+
+ for (i = 0; i < c->n_playlists; i++) {
+ struct playlist *pls = c->playlists[i];
--- /dev/null
+--- a/libavformat/mov.c
++++ b/libavformat/mov.c
+@@ -3966,8 +3966,10 @@
+
+ if (ctts_data_old && ctts_index_old < ctts_count_old) {
+ curr_ctts = ctts_data_old[ctts_index_old].duration;
++ /*
+ av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
+ curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
++ */
+ curr_cts += curr_ctts;
+ ctts_sample_old++;
+ if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
--- /dev/null
+--- a/libavformat/dashdec.c
++++ b/libavformat/dashdec.c
+@@ -1400,6 +1400,9 @@
+ } else {
+ num = pls->first_seq_no + (((c->publish_time - c->time_shift_buffer_depth + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
+ }
++ } else if (c->period_start && c->availability_start_time && pls->fragment_timescale) {
++ num = pls->first_seq_no + ((( get_current_time_in_sec() - (c->availability_start_time + c->period_start)) * pls->fragment_timescale) - pls->fragment_duration)/ pls->fragment_duration;
++
+ } else {
+ num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
+ }
--- /dev/null
+--- a/libavformat/rtsp.c
++++ b/libavformat/rtsp.c
+@@ -2392,6 +2392,8 @@ static int sdp_read_header(AVFormatContext *s)
+ int i, err;
+ char url[MAX_URL_SIZE];
+ AVBPrint bp;
++ const char *p, *sp="", *sources="", *sp2, *sources2;
++ char sources_buf[1024];
+
+ if (!ff_network_init())
+ return AVERROR(EIO);
+@@ -2413,6 +2415,16 @@ static int sdp_read_header(AVFormatContext *s)
+ av_bprint_finalize(&bp, NULL);
+ if (err) goto fail;
+
++ /* Search for sources= tag in original URL for rtp protocol only */
++ if (strncmp(s->url, "rtp://", 6) == 0) {
++ p = strchr(s->url, '?');
++ if (p && av_find_info_tag(sources_buf, sizeof(sources_buf), "sources", p)) {
++ /* av_log(s, AV_LOG_VERBOSE, "sdp_read_header found sources %s\n", sources_buf); */
++ sp = sources_buf;
++ sources = "&sources=";
++ }
++ }
++
+ /* open each RTP stream */
+ for (i = 0; i < rt->nb_rtsp_streams; i++) {
+ char namebuf[50];
+@@ -2432,12 +2445,22 @@ static int sdp_read_header(AVFormatContext *s)
+ av_dict_free(&opts);
+ goto fail;
+ }
++
++ /* Prepare to add sources to the url to be opened.
++ Otherwise the join to the source specific muliticast will be missing */
++ sources2 = sources;
++ sp2 = sp;
++ /* ignore sources from original URL, when sources are already set in rtsp_st */
++ if (rtsp_st->nb_include_source_addrs > 0)
++ sources2 = sp2 = "";
++
+ ff_url_join(url, sizeof(url), "rtp", NULL,
+ namebuf, rtsp_st->sdp_port,
+- "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
++ "?localport=%d&ttl=%d&connect=%d&write_to_source=%d%s%s",
+ rtsp_st->sdp_port, rtsp_st->sdp_ttl,
+ rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
+- rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
++ rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0,
++ sources2, sp2);
+
+ p = strchr(s->url, '?');
+ if (p && av_find_info_tag(buf, sizeof(buf), "localaddr", p))
--- /dev/null
+--- a/libavcodec/dxva2.c
++++ b/libavcodec/dxva2.c
+@@ -777,16 +777,18 @@
+ #if CONFIG_D3D11VA
+ if (avctx->pix_fmt == AV_PIX_FMT_D3D11)
+ return (intptr_t)frame->data[1];
+- if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
++ if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && surface) {
+ D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
+ ID3D11VideoDecoderOutputView_GetDesc((ID3D11VideoDecoderOutputView*) surface, &viewDesc);
+ return viewDesc.Texture2D.ArraySlice;
+ }
+ #endif
+ #if CONFIG_DXVA2
+- for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
+- if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
+- return i;
++ if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
++ for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
++ if (ctx->dxva2.surface[i] == surface)
++ return i;
++ }
+ }
+ #endif
+
+--- a/libavcodec/dxva2_h264.c
++++ b/libavcodec/dxva2_h264.c
+@@ -507,6 +507,14 @@
+
+ if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
+ return -1;
++
++ // Wait for an I-frame before start decoding. Workaround for ATI UVD and UVD+ GPUs
++ if (!h->got_first_iframe) {
++ if (!(ctx_pic->pp.wBitFields & (1 << 15)))
++ return -1;
++ h->got_first_iframe = 1;
++ }
++
+ ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr->f,
+ &ctx_pic->pp, sizeof(ctx_pic->pp),
+ &ctx_pic->qm, sizeof(ctx_pic->qm),
+--- a/libavcodec/h264_slice.c
++++ b/libavcodec/h264_slice.c
+@@ -978,6 +978,7 @@
+
+ h->first_field = 0;
+ h->prev_interlaced_frame = 1;
++ h->got_first_iframe = 0;
+
+ init_scan_tables(h);
+ ret = ff_h264_alloc_tables(h);
+--- a/libavcodec/h264dec.c
++++ b/libavcodec/h264dec.c
+@@ -456,6 +456,7 @@
+
+ h->next_outputed_poc = INT_MIN;
+ h->prev_interlaced_frame = 1;
++ h->got_first_iframe = 0;
+ idr(h);
+
+ h->poc.prev_frame_num = -1;
+--- a/libavcodec/h264dec.h
++++ b/libavcodec/h264dec.h
+@@ -533,6 +533,8 @@
+ * slices) anymore */
+ int setup_finished;
+
++ int got_first_iframe;
++
+ int cur_chroma_format_idc;
+ int cur_bit_depth_luma;
+ int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
+--- a/libavcodec/vaapi_h264.c
++++ b/libavcodec/vaapi_h264.c
+@@ -314,6 +314,11 @@
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int ret;
+
++ if (pic->nb_slices == 0) {
++ ret = AVERROR_INVALIDDATA;
++ goto finish;
++ }
++
+ ret = ff_vaapi_decode_issue(avctx, pic);
+ if (ret < 0)
+ goto finish;
+--- a/libavformat/bintext.c
++++ b/libavformat/bintext.c
+@@ -149,7 +149,7 @@
+ return AVPROBE_SCORE_EXTENSION + 1;
+
+ predict_width(&par, p->buf_size, got_width);
+- if (par.width < 8)
++ if (par.width <= 0)
+ return 0;
+ calculate_height(&par, p->buf_size);
+ if (par.height <= 0)
+@@ -189,8 +189,6 @@
+ next_tag_read(s, &bin->fsize);
+ if (!bin->width) {
+ predict_width(st->codecpar, bin->fsize, got_width);
+- if (st->codecpar->width < 8)
+- return AVERROR_INVALIDDATA;
+ calculate_height(st->codecpar, bin->fsize);
+ }
+ avio_seek(pb, 0, SEEK_SET);
--- /dev/null
+--- a/libavformat/avformat.h
++++ b/libavformat/avformat.h
+@@ -1030,6 +1030,10 @@
+ int64_t av_stream_get_end_pts(const AVStream *st);
+ #endif
+
++// Chromium: We use the internal field first_dts vvv
++int64_t av_stream_get_first_dts(const AVStream *st);
++// Chromium: We use the internal field first_dts ^^^
++
+ #define AV_PROGRAM_RUNNING 1
+
+ /**
+--- a/libavformat/utils.c
++++ b/libavformat/utils.c
+@@ -100,6 +100,13 @@
+ return pkt->size > orig_size ? pkt->size - orig_size : ret;
+ }
+
++// Chromium: We use the internal field first_dts vvv
++int64_t av_stream_get_first_dts(const AVStream *st)
++{
++ return cffstream(st)->first_dts;
++}
++// Chromium: We use the internal field first_dts ^^^
++
+ int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
+ {
+ #if FF_API_INIT_PACKET
--- /dev/null
+--- a/libavformat/avio.c
++++ b/libavformat/avio.c
+@@ -171,12 +171,12 @@
+ (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value)));
+ av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
+ (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value)));
+-
++/*
+ if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) {
+ av_log(uc, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", uc->prot->name, uc->protocol_whitelist);
+ return AVERROR(EINVAL);
+ }
+-
++*/
+ if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) {
+ av_log(uc, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", uc->prot->name, uc->protocol_blacklist);
+ return AVERROR(EINVAL);
--- /dev/null
+--- a/doc/demuxers.texi
++++ b/doc/demuxers.texi
+@@ -281,7 +281,11 @@
+ @table @option
+
+ @item cenc_decryption_key
+-16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
++Default 16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
++
++ at item cenc_decryption_keys
++Dictionary of 16-byte key ID => 16-byte key, both in hex, to decrypt files encrypted using ISO Common Encryption
++(CENC/AES-128 CTR; ISO/IEC 23001-7).
+
+ @end table
+
+@@ -769,7 +773,11 @@
+ specify.
+
+ @item decryption_key
+-16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
++Default 16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
++
++ at item decryption_keys
++Dictionary of 16-byte key ID => 16-byte key, both in hex, to decrypt files encrypted using ISO Common Encryption
++(CENC/AES-128 CTR; ISO/IEC 23001-7).
+
+ @item max_stts_delta
+ Very high sample deltas written in a trak's stts box may occasionally be intended but usually they are written in
+--- a/libavformat/dashdec.c
++++ b/libavformat/dashdec.c
+@@ -153,6 +153,7 @@
+ AVDictionary *avio_opts;
+ int max_url_size;
+ char *cenc_decryption_key;
++ char *cenc_decryption_keys;
+
+ /* Flags for init section*/
+ int is_init_section_common_video;
+@@ -1906,6 +1907,8 @@
+
+ if (c->cenc_decryption_key)
+ av_dict_set(&in_fmt_opts, "decryption_key", c->cenc_decryption_key, 0);
++ if (c->cenc_decryption_keys)
++ av_dict_set(&in_fmt_opts, "decryption_keys", c->cenc_decryption_keys, 0);
+
+ // provide additional information from mpd if available
+ ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts); //pls->init_section->url
+@@ -2347,7 +2350,8 @@
+ OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
+ {.str = "aac,m4a,m4s,m4v,mov,mp4,webm,ts"},
+ INT_MIN, INT_MAX, FLAGS},
+- { "cenc_decryption_key", "Media decryption key (hex)", OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
++ { "cenc_decryption_key", "Media default decryption key (hex)", OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
++ { "cenc_decryption_keys", "Media decryption keys by KID (hex)", OFFSET(cenc_decryption_keys), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS },
+ {NULL}
+ };
+
+--- a/libavformat/isom.h
++++ b/libavformat/isom.h
+@@ -312,8 +312,8 @@
+ void *audible_iv;
+ int audible_iv_size;
+ struct AVAES *aes_decrypt;
+- uint8_t *decryption_key;
+- int decryption_key_len;
++ uint8_t *decryption_default_key;
++ int decryption_default_key_len;
+ int enable_drefs;
+ int32_t movie_display_matrix[3][3]; ///< display matrix from mvhd
+ int have_read_mfra_size;
+@@ -328,6 +328,7 @@
+ } *avif_info;
+ int avif_info_size;
+ int interleaved_read;
++ AVDictionary* decryption_keys;
+ } MOVContext;
+
+ int ff_mp4_read_descr_len(AVIOContext *pb);
+--- a/libavformat/mov.c
++++ b/libavformat/mov.c
+@@ -7130,19 +7130,62 @@
+ return 0;
+ }
+
++static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
++ AVDictionaryEntry *key_entry_hex;
++ char kid_hex[16*2+1];
++
++ if (c->decryption_default_key && c->decryption_default_key_len != len) {
++ av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
++ return -1;
++ }
++
++ if (!c->decryption_keys) {
++ av_assert0(c->decryption_default_key);
++ memcpy(out, c->decryption_default_key, len);
++ return 0;
++ }
++
++ if (sample->key_id_size != 16) {
++ av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
++ return -1;
++ }
++
++ ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
++ key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
++ if (!key_entry_hex) {
++ if (!c->decryption_default_key) {
++ av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
++ return -1;
++ }
++ memcpy(out, c->decryption_default_key, len);
++ return 0;
++ }
++ if (strlen(key_entry_hex->value) != len*2) {
++ return -1;
++ }
++ ff_hex_to_data(out, key_entry_hex->value);
++ return 0;
++}
++
+ static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
+ {
+ int i, ret;
+ int bytes_of_protected_data;
++ uint8_t decryption_key[AES_CTR_KEY_SIZE];
+
+ if (!sc->cenc.aes_ctr) {
++ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
++ if (ret < 0) {
++ return ret;
++ }
++
+ /* 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);
++ ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
+ if (ret < 0) {
+ return ret;
+ }
+@@ -7188,15 +7231,21 @@
+ int i, ret;
+ int num_of_encrypted_blocks;
+ uint8_t iv[16];
++ uint8_t decryption_key[16];
+
+ if (!sc->cenc.aes_ctx) {
++ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
++ if (ret < 0) {
++ return ret;
++ }
++
+ /* 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);
++ ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
+ if (ret < 0) {
+ return ret;
+ }
+@@ -7247,15 +7296,21 @@
+ {
+ int i, ret, rem_bytes;
+ uint8_t *data;
++ uint8_t decryption_key[AES_CTR_KEY_SIZE];
+
+ if (!sc->cenc.aes_ctr) {
++ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
++ if (ret < 0) {
++ return ret;
++ }
++
+ /* 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);
++ ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
+ if (ret < 0) {
+ return ret;
+ }
+@@ -7313,15 +7368,21 @@
+ int i, ret, rem_bytes;
+ uint8_t iv[16];
+ uint8_t *data;
++ uint8_t decryption_key[16];
+
+ if (!sc->cenc.aes_ctx) {
++ ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
++ if (ret < 0) {
++ return ret;
++ }
++
+ /* 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);
++ ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
+ if (ret < 0) {
+ return ret;
+ }
+@@ -7464,7 +7525,7 @@
+ return AVERROR_INVALIDDATA;
+ }
+
+- if (mov->decryption_key) {
++ if (mov->decryption_keys || mov->decryption_default_key) {
+ return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
+ } else {
+ size_t size;
+@@ -8613,12 +8674,6 @@
+ MOVAtom atom = { AV_RL32("root") };
+ int i;
+
+- if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
+- av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
+- mov->decryption_key_len, AES_CTR_KEY_SIZE);
+- return AVERROR(EINVAL);
+- }
+-
+ mov->fc = s;
+ mov->trak_index = -1;
+ /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
+@@ -9317,7 +9372,8 @@
+ "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
+ AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
+ .flags = AV_OPT_FLAG_DECODING_PARAM },
+- { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
++ { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
++ { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
+ { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
+ {.i64 = 0}, 0, 1, FLAGS },
+ { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM },
+--- a/tests/fate/mov.mak
++++ b/tests/fate/mov.mak
+@@ -8,6 +8,9 @@
+ fate-mov-3elist-encrypted \
+ fate-mov-frag-encrypted \
+ fate-mov-tenc-only-encrypted \
++ fate-mov-3elist-encrypted-kid \
++ fate-mov-frag-encrypted-kid \
++ fate-mov-tenc-only-encrypted-kid \
+ fate-mov-invalid-elst-entry-count \
+ fate-mov-gpmf-remux \
+ fate-mov-440hz-10ms \
+@@ -57,6 +60,15 @@ fate-mov-frag-encrypted: CMD = framemd5 -decryption_key 123456789012345678901234
+ # Full-sample encryption and constant IV using only tenc atom (no senc/saio/saiz).
+ fate-mov-tenc-only-encrypted: CMD = framemd5 -decryption_key 12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-tenc-only-encrypted.mp4
+
++# Edit list with encryption, using the decryption_keys option.
++fate-mov-3elist-encrypted-kid: CMD = framemd5 -decryption_keys 12345678901234567890123456789012=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-3elist-encrypted.mov
++
++# Fragmented encryption with senc boxes in movie fragments, using the decryption_keys option.
++fate-mov-frag-encrypted-kid: CMD = framemd5 -decryption_keys abba271e8bcf552bbd2e86a434a9a5d9=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-frag-encrypted.mp4
++
++# Full-sample encryption and constant IV using only tenc atom (no senc/saio/saiz), using the decryption_keys option.
++fate-mov-tenc-only-encrypted-kid: CMD = framemd5 -decryption_keys abba271e8bcf552bbd2e86a434a9a5d9=12345678901234567890123456789012 -i $(TARGET_SAMPLES)/mov/mov-tenc-only-encrypted.mp4
++
+ # Makes sure that the CTTS is also modified when we fix avindex in mov.c while parsing edit lists.
+ fate-mov-elist-starts-ctts-2ndsample: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-elist-starts-ctts-2ndsample.mov
+
+--- /dev/null
++++ b/tests/ref/fate/mov-3elist-encrypted-kid
+@@ -0,0 +1,57 @@
++#format: frame checksums
++#version: 2
++#hash: MD5
++#tb 0: 1/24
++#media_type 0: video
++#codec_id 0: rawvideo
++#dimensions 0: 640x480
++#sar 0: 0/1
++#stream#, dts, pts, duration, size, hash
++0, 0, 0, 1, 460800, 80fbbdec589e15e6c493b44d243f92a9
++0, 1, 1, 1, 460800, f4b23293bb2ecf69cc3570853d8c56a1
++0, 2, 2, 1, 460800, 0c03ce2c1c6ec405d7455465ecd559a3
++0, 3, 3, 1, 460800, 7921791695537fba2c3c123da4834cb9
++0, 4, 4, 1, 460800, 30c8e2903a561b84d4cbaf95c668d236
++0, 5, 5, 1, 460800, 7ff42e998217c17592ddf6b584f26cef
++0, 6, 6, 1, 460800, 5e402c48bf097db2d31b82bb4194a382
++0, 7, 7, 1, 460800, 824c49e92c8ae6d99a0207b514dd756c
++0, 8, 8, 1, 460800, 24f189216a1d9cf2313b2d6dbe3dbdd3
++0, 9, 9, 1, 460800, 519179a8e74275d26b183374637e003f
++0, 10, 10, 1, 460800, f18331ddcef0adf5b069bfa98baf8db4
++0, 11, 11, 1, 460800, 081f61688690d47dbdddd5384e5d5a70
++0, 12, 12, 1, 460800, 90dbf019b9035433371a8df41a9268b7
++0, 13, 13, 1, 460800, bb5adfb9c66732898b34186eca1667ba
++0, 14, 14, 1, 460800, cc08cfd64f37783ecddaf143f6ad78bc
++0, 15, 15, 1, 460800, b8ae21d024fe4df903d56f4521993c72
++0, 16, 16, 1, 460800, b45a99907f045dcadf0a2befc11555e3
++0, 17, 17, 1, 460800, 603ba935845e65ab6cccbbec88bbf60d
++0, 18, 18, 1, 460800, df80c8d3e6a77258a306903f17995a18
++0, 19, 19, 1, 460800, 4b7e90c0a5fd0e0cd958d47f0afac636
++0, 20, 20, 1, 460800, 9feb6e36182f1745be6387edea240eb6
++0, 21, 21, 1, 460800, 86e6de4bd0a5ff7558f4cf6c1ec3930d
++0, 22, 22, 1, 460800, 726b69df77edbe7b503d4698656d1320
++0, 23, 23, 1, 460800, d282fb7a953ac205b0a43d00c2d60a33
++0, 24, 24, 1, 460800, eece3daa70cc20208dd75d91ac84c8fd
++0, 25, 25, 1, 460800, c86d23e73bcce351fc315fb1f13348da
++0, 26, 26, 1, 460800, 93497b4f7c5ad9d61212239b7c9d2770
++0, 27, 27, 1, 460800, eb217d2c12de67903835a8c58f620488
++0, 28, 28, 1, 460800, d966480867bb54c8cd044f18388ed486
++0, 29, 29, 1, 460800, 3ea6207942b3181fdd8e8aa6cae1062a
++0, 30, 30, 1, 460800, 2620df54aca086ec0fb9527c6e6f5135
++0, 31, 31, 1, 460800, 43bb7320f0bb583188dc965ddbfade90
++0, 32, 32, 1, 460800, 0cddaa04645f804e02f65b0836412113
++0, 33, 33, 1, 460800, 83b2dc95807289d7f4a4632bf18c2e97
++0, 34, 34, 1, 460800, 98134d0e41e6dd12827049ccf33b4669
++0, 35, 35, 1, 460800, 56f55631731fa39c7acbab0afeb2eb1b
++0, 36, 36, 1, 460800, 379c1105be09d836a515dc909455ddf4
++0, 37, 37, 1, 460800, 1df87c47e9d98731faf1c3885b77e5da
++0, 38, 38, 1, 460800, 9a8734bcbfdb4d97e530683b8b556a26
++0, 39, 39, 1, 460800, c7a7990d0cddc5adfbe27da7a42e025e
++0, 40, 40, 1, 460800, 0c81e46011e03be410feaf056207fd55
++0, 41, 41, 1, 460800, ca76e4e63016ff29d8aeeb9cb053bb6c
++0, 42, 42, 1, 460800, cebfbe299c17c1f8fc1e6b189555c3c2
++0, 43, 43, 1, 460800, 4f002c5feca5e75f07089e0df47507dd
++0, 44, 44, 1, 460800, c5fd83fc4a745abee9b3d9a6eec9dd3e
++0, 45, 45, 1, 460800, 57d9bad9b45aa2746de5d8bdc2c24969
++0, 46, 46, 1, 460800, 9831673ad7dec167af4a959f64258949
++0, 47, 47, 1, 460800, 77a1cb208f70f51bcb01e28d8cba73b4
+--- /dev/null
++++ b/tests/ref/fate/mov-frag-encrypted-kid
+@@ -0,0 +1,57 @@
++#format: frame checksums
++#version: 2
++#hash: MD5
++#tb 0: 1/24
++#media_type 0: video
++#codec_id 0: rawvideo
++#dimensions 0: 120x52
++#sar 0: 544/545
++#stream#, dts, pts, duration, size, hash
++0, 0, 0, 1, 9360, 920bdc277a6a31c1daed9aca44b10caf
++0, 1, 1, 1, 9360, f1c0b61fef593de57cb97be7fa846569
++0, 2, 2, 1, 9360, 6ef32d9d4398355aebf6d3fb11d51d3f
++0, 3, 3, 1, 9360, d38fd3ef1e5a92fc109b8dd9eb6dadeb
++0, 4, 4, 1, 9360, 54cc0c8a25d2f14f32663837d5e646f1
++0, 5, 5, 1, 9360, b4b6829726dc3decb8b80ba0c35bcf30
++0, 6, 6, 1, 9360, fca3f941e60a2f0a4ce30d5e0efbec3c
++0, 7, 7, 1, 9360, cda6e26b6c1039ff3d229b262c9210c3
++0, 8, 8, 1, 9360, f0d69255e3a27a8b4ae8a4b7b210929d
++0, 9, 9, 1, 9360, 12cb23dd4e32af9c3b35f943714e3fdd
++0, 10, 10, 1, 9360, 082aaf3216124ddcecb422fe5c832e82
++0, 11, 11, 1, 9360, ff37bb8cd6bd0412a3b3cb45db54afc9
++0, 12, 12, 1, 9360, dfb9085441575732844b6c2f05d5f542
++0, 13, 13, 1, 9360, 0017100feaaa9fc7eacd2447d50d7542
++0, 14, 14, 1, 9360, 4e2f1b8c4e04c59934c2f58541e62613
++0, 15, 15, 1, 9360, 27a44dfea7cd2d30e488194c34ab473c
++0, 16, 16, 1, 9360, fc7b56bd95e990a33cf575d1ef820902
++0, 17, 17, 1, 9360, fa2d1609e69714dffc410e65f3c8b755
++0, 18, 18, 1, 9360, 705d7429f447cb13febe202d567795f2
++0, 19, 19, 1, 9360, 234802ce86e868faaf2cd40a286846ea
++0, 20, 20, 1, 9360, 2f0354b40d211d0a4ade4568bea4f85e
++0, 21, 21, 1, 9360, e96af3b6c0cc931463ca77d6be0f1148
++0, 22, 22, 1, 9360, 04a904d798361959971361401879c7e4
++0, 23, 23, 1, 9360, 2f119642340df6d25362b5590ded46b7
++0, 24, 24, 1, 9360, 5993fca2e60050706f857ac76e48f386
++0, 25, 25, 1, 9360, 2ff3b5775fed3d527bfbbeea786787fe
++0, 26, 26, 1, 9360, 42024dbe23d3fb5b0d8987ae1ce390a8
++0, 27, 27, 1, 9360, d804204f0bd9db5f6a758e2c934d9e38
++0, 28, 28, 1, 9360, e322712e6e34c58ec1a2ab5e2c1e3bfe
++0, 29, 29, 1, 9360, 3975bd1a5f6a6b6260276777f9de611e
++0, 30, 30, 1, 9360, 4388f0412efc6310706a7cdedc859ea9
++0, 31, 31, 1, 9360, b4b9a11b0b86635267345a569640e8d4
++0, 32, 32, 1, 9360, 31879c7b8d6b67a4209ffde786bb8cb4
++0, 33, 33, 1, 9360, 4b6dc02d7c889fe4abd4e013b25f585a
++0, 34, 34, 1, 9360, dc73aae82bd39a1220d1106c8d3e8252
++0, 35, 35, 1, 9360, 54c7dfbd49f312806f6c1a89f7c2c36f
++0, 36, 36, 1, 9360, 150abc64f8994d444a521ea90570443c
++0, 37, 37, 1, 9360, d277cdc7dcadbe0016f2e950459e7ebf
++0, 38, 38, 1, 9360, 2196bf338ead90ea54687b85c73c8229
++0, 39, 39, 1, 9360, 53ce5da5365abc0bd3217dd98e7c465d
++0, 40, 40, 1, 9360, 34ee9832aea55c0c4e6f4381c413c10e
++0, 41, 41, 1, 9360, 1769c7b5849e4681119067a06ac29a4f
++0, 42, 42, 1, 9360, 71f53df739ef283a5184c91ef4b158e8
++0, 43, 43, 1, 9360, d2d394739e9a59c06f0354c16843cb63
++0, 44, 44, 1, 9360, d8e458e92ae29344505a24a3059fc584
++0, 45, 45, 1, 9360, 0f1b11a09911851b798df2ef76253a7f
++0, 46, 46, 1, 9360, 5c4a9f22baecf4e749c0d5c65a4f1007
++0, 47, 47, 1, 9360, 3e2b7e7262fdca08d9d1ef6070125c4b
+--- /dev/null
++++ b/tests/ref/fate/mov-tenc-only-encrypted-kid
+@@ -0,0 +1,57 @@
++#format: frame checksums
++#version: 2
++#hash: MD5
++#tb 0: 1/24
++#media_type 0: video
++#codec_id 0: rawvideo
++#dimensions 0: 1024x436
++#sar 0: 1/1
++#stream#, dts, pts, duration, size, hash
++0, 0, 0, 1, 669696, f48f296a85eda5ba069dc851a3228bef
++0, 1, 1, 1, 669696, a50c5f69bfa3387d49b5bdf738e6529c
++0, 2, 2, 1, 669696, 05061299003760f6a4795b408f72aa31
++0, 3, 3, 1, 669696, 2572119f0b0cdd83f8a7e06252cecd3b
++0, 4, 4, 1, 669696, 29fe6a6bdb4a69018e318886a297f07e
++0, 5, 5, 1, 669696, e8233c7fbaecfbff965c7dfdd3982b1b
++0, 6, 6, 1, 669696, d9259df9880ff5d4a4b38282e67f407b
++0, 7, 7, 1, 669696, 3e8d795195038993503ea9ab6984c915
++0, 8, 8, 1, 669696, bc4e2d253b715a34f85aae1b080e3460
++0, 9, 9, 1, 669696, 09aba8b3a96f53f9268e7420a10bfab6
++0, 10, 10, 1, 669696, 179447977dd580da8b35fb5310a809ca
++0, 11, 11, 1, 669696, 7a0eea9d54577990345f5705ab9882be
++0, 12, 12, 1, 669696, 5bb96eb76f461825740e5938456df759
++0, 13, 13, 1, 669696, bd4ac4a760ead774b9422a27dc071964
++0, 14, 14, 1, 669696, 1cc05f760a9b751fc89e77f2bcc97259
++0, 15, 15, 1, 669696, 825d0dee6f0174ba7102892c7de30b4d
++0, 16, 16, 1, 669696, d26a2ef5267f6bb03c4e1d8514eee0df
++0, 17, 17, 1, 669696, c916ffdeadca76596a8f7fd47914b5ef
++0, 18, 18, 1, 669696, 6e085acfa7fee0658ea0ae6188274c17
++0, 19, 19, 1, 669696, 1e95fa5b3561283f05bf0bd44cb91721
++0, 20, 20, 1, 669696, 37e3d135aba9dfb8b87e441753115374
++0, 21, 21, 1, 669696, 9c398310e8564491de624393c16265ce
++0, 22, 22, 1, 669696, c87209e4d2617bc2ab40a75f455f09da
++0, 23, 23, 1, 669696, 2679c2f8d1d1af21982e245945c1ee60
++0, 24, 24, 1, 669696, 6151ab4781f31c5beb66b356ad547122
++0, 25, 25, 1, 669696, f7ef6293bfb3a6a329061cb6a5ed5a38
++0, 26, 26, 1, 669696, 2f6e666d14dfc407ca0c0f347b13eb08
++0, 27, 27, 1, 669696, 3454fa1730d79b1aa8dbbc865dc150f4
++0, 28, 28, 1, 669696, e93dc683e2453419a0419ab9af0f8f95
++0, 29, 29, 1, 669696, 031eb3154f7f83cf86d42bee66be9cf7
++0, 30, 30, 1, 669696, 1205c36723e88811206c68892d3aaed6
++0, 31, 31, 1, 669696, 7dd7a8a19dcd73b31ddc6a6d0c597a42
++0, 32, 32, 1, 669696, 7c91115368ea2531262a1197468bc3f4
++0, 33, 33, 1, 669696, 3cf6d9ba385e0fff76da33299ed5380c
++0, 34, 34, 1, 669696, 859fc8c3ef049e3c1175a85fb0a90a3d
++0, 35, 35, 1, 669696, 1d09ce6c7027103d99a4d5799f6e72ab
++0, 36, 36, 1, 669696, 3dcb8357408ac88abd734128d8f5dd6f
++0, 37, 37, 1, 669696, 4dafce137a0a5178f6efaec878e64d36
++0, 38, 38, 1, 669696, 44c478f29a1399ed03275a7357f57d48
++0, 39, 39, 1, 669696, 6e9edaac7414c0e14591ac3d4d0b1ac4
++0, 40, 40, 1, 669696, 522e4aaeea0825da27f631a9e690d654
++0, 41, 41, 1, 669696, 85f2502a718440834c40051d30f8a65e
++0, 42, 42, 1, 669696, ae8816f7bd4645ef1a17ee6d09b4c8d2
++0, 43, 43, 1, 669696, 914b006fa92f1eb3e590245749f6810d
++0, 44, 44, 1, 669696, 9406901542e94c429dff46108782ed69
++0, 45, 45, 1, 669696, 324c13641c39eef5c476023e358c0391
++0, 46, 46, 1, 669696, 4058e886e17c22e4eb9da1dd0d6ad891
++0, 47, 47, 1, 669696, 9edf9cd15eea985b42fd1f5035b1d693
+--
--- /dev/null
+diff --git a/libavutil/common.h b/libavutil/common.h
+index fd1404be6c..0bb8650e83 100644
+--- a/libavutil/common.h
++++ b/libavutil/common.h
+@@ -351,7 +351,8 @@ static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) {
+ return !__builtin_add_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN);
+ #else
+ int64_t s = a+(uint64_t)b;
+- if ((int64_t)(a^b | ~s^b) >= 0)
++ // PATCH: GCC 4.9.4 complains about missing parentheses when combining bitwise operations.
++ if ((int64_t)((a^b) | (~s^b)) >= 0)
+ return INT64_MAX ^ (b >> 63);
+ return s;
+ #endif
--- /dev/null
+diff --git a/libavcodec/Makefile b/libavcodec/Makefile
+index 457ec58377..49bf260764 100644
+--- a/libavcodec/Makefile
++++ b/libavcodec/Makefile
+@@ -1209,6 +1209,8 @@ OBJS-$(CONFIG_SETTS_BSF) += setts_bsf.o
+ OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o
+ OBJS-$(CONFIG_TRACE_HEADERS_BSF) += trace_headers_bsf.o
+ OBJS-$(CONFIG_TRUEHD_CORE_BSF) += truehd_core_bsf.o mlp_parse.o mlp.o
++OBJS-$(CONFIG_VC1_ASFTORCV_BSF) += vc1_asftorcv_bsf.o
++OBJS-$(CONFIG_VC1_ASFTOANNEXG_BSF) += vc1_asftoannexg_bsf.o vc1.o
+ OBJS-$(CONFIG_VP9_METADATA_BSF) += vp9_metadata_bsf.o
+ OBJS-$(CONFIG_VP9_RAW_REORDER_BSF) += vp9_raw_reorder_bsf.o
+ OBJS-$(CONFIG_VP9_SUPERFRAME_BSF) += vp9_superframe_bsf.o
+diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
+index 444423ae93..482d3473b2 100644
+--- a/libavcodec/bitstream_filters.c
++++ b/libavcodec/bitstream_filters.c
+@@ -59,6 +59,8 @@ extern const FFBitStreamFilter ff_setts_bsf;
+ extern const FFBitStreamFilter ff_text2movsub_bsf;
+ extern const FFBitStreamFilter ff_trace_headers_bsf;
+ extern const FFBitStreamFilter ff_truehd_core_bsf;
++extern const FFBitStreamFilter ff_vc1_asftoannexg_bsf;
++extern const FFBitStreamFilter ff_vc1_asftorcv_bsf;
+ extern const FFBitStreamFilter ff_vp9_metadata_bsf;
+ extern const FFBitStreamFilter ff_vp9_raw_reorder_bsf;
+ extern const FFBitStreamFilter ff_vp9_superframe_bsf;
+diff --git a/libavcodec/vc1_asftoannexg_bsf.c b/libavcodec/vc1_asftoannexg_bsf.c
+new file mode 100644
+index 0000000000..2901f84d9c
+--- /dev/null
++++ b/libavcodec/vc1_asftoannexg_bsf.c
+@@ -0,0 +1,190 @@
++/*
++ * copyright (c) 2010 Google Inc.
++ * copyright (c) 2013 CoolStream International Ltd.
++ * copyright (c) 2017 Jacek Jendrzej port to 3.x
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "avcodec.h"
++#include "bytestream.h"
++#include "vc1.h"
++#include "bsf.h"
++#include "bsf_internal.h"
++
++// An arbitrary limit in bytes greater than the current bytes used.
++#define MAX_SEQ_HEADER_SIZE 50
++
++typedef struct ASFTOANNEXGBSFContext {
++ int frames;
++ uint8_t *seq_header;
++ int seq_header_size;
++ uint8_t *ep_header;
++ int ep_header_size;
++} ASFTOANNEXGBSFContext;
++
++static int find_codec_data(ASFTOANNEXGBSFContext *ctx, uint8_t *data, int data_size, int keyframe) {
++ const uint8_t *start = data;
++ const uint8_t *end = data + data_size;
++ const uint8_t *next;
++ int size;
++ int has_seq_header = 0;
++ int has_ep_header = 0;
++ int has_frame_header = 0;
++
++ start = find_next_marker(start, end);
++ next = start;
++ for(; next < end; start = next){
++ next = find_next_marker(start + 4, end);
++ size = next - start;
++ if(size <= 0) continue;
++ switch(AV_RB32(start)){
++ case VC1_CODE_SEQHDR:
++ has_seq_header = 1;
++ break;
++ case VC1_CODE_ENTRYPOINT:
++ has_ep_header = 1;
++ break;
++ case VC1_CODE_FRAME:
++ has_frame_header = 1;
++ break;
++ default:
++ break;
++ }
++ }
++
++ if((has_seq_header && has_ep_header && has_frame_header && keyframe) ||
++ (!has_seq_header && !has_ep_header && has_frame_header) ) return 0;
++
++ return -1;
++}
++
++static int parse_extradata(ASFTOANNEXGBSFContext *ctx, uint8_t *extradata, int extradata_size) {
++ const uint8_t *start = extradata;
++ const uint8_t *end = extradata + extradata_size;
++ const uint8_t *next;
++ int size;
++
++ start = find_next_marker(start, end);
++ next = start;
++ for(; next < end; start = next){
++ next = find_next_marker(start + 4, end);
++ size = next - start;
++ if(size <= 0) continue;
++ switch(AV_RB32(start)){
++ case VC1_CODE_SEQHDR:
++ ctx->seq_header = av_mallocz(size);
++ ctx->seq_header_size = size;
++ memcpy(ctx->seq_header, start, size);
++ break;
++ case VC1_CODE_ENTRYPOINT:
++ ctx->ep_header = av_malloc(size);
++ ctx->ep_header_size = size;
++ memcpy(ctx->ep_header, start, size);
++ break;
++ default:
++ break;
++ }
++ }
++
++ if(!ctx->seq_header || !ctx->ep_header) {
++ av_log(NULL, AV_LOG_ERROR, "Incomplete extradata\n");
++ return -1;
++ }
++ return 0;
++}
++
++static int asftoannexg_filter(AVBSFContext *ctx, AVPacket *out)
++{
++ ASFTOANNEXGBSFContext* bsfctx = ctx->priv_data;
++ AVPacket *in;
++ int keyframe;
++ int ret;
++ uint8_t* bs = NULL;
++
++ ret = ff_bsf_get_packet(ctx, &in);
++ if (ret < 0)
++ return ret;
++
++ keyframe = in->flags & AV_PKT_FLAG_KEY;
++ if(in->size >= 1 && !find_codec_data(bsfctx, in->data, in->size, keyframe)) {
++// av_log(NULL, AV_LOG_INFO, "Nothing to do: %i\n",in->size);
++ av_packet_move_ref(out, in);
++ av_packet_free(&in);
++ return 0;
++ }
++
++ if(!ctx->par_in->extradata || ctx->par_in->extradata_size < 16) {
++ av_log(NULL, AV_LOG_INFO, "Extradata size too small: %i\n", ctx->par_in->extradata_size);
++ av_packet_move_ref(out, in);
++ av_packet_free(&in);
++ return 0;
++ }
++
++ if (!bsfctx->frames && parse_extradata(bsfctx, ctx->par_in->extradata , ctx->par_in->extradata_size) < 0) {
++ av_packet_free(&in);
++ av_log(NULL, AV_LOG_ERROR, "Cannot parse extra data!\n");
++ return -1;
++ }
++
++ if (keyframe) {
++ // If this is the keyframe, need to put sequence header and entry point header.
++ ret = av_new_packet(out, bsfctx->seq_header_size + bsfctx->ep_header_size + 4 + in->size);
++ if (ret < 0)
++ goto exit;
++ bs = out->data;
++
++ memcpy(bs, bsfctx->seq_header, bsfctx->seq_header_size);
++ bs += bsfctx->seq_header_size;
++ memcpy(bs, bsfctx->ep_header, bsfctx->ep_header_size);
++ bs += bsfctx->ep_header_size;
++ } else {
++ ret = av_new_packet(out, 4 + in->size);
++ if (ret < 0)
++ goto exit;
++ bs = out->data;
++ }
++
++ // Put the frame start code and frame data.
++ bytestream_put_be32(&bs, VC1_CODE_FRAME);
++ memcpy(bs, in->data, in->size);
++ ++bsfctx->frames;
++
++ ret = av_packet_copy_props(out, in);
++
++exit:
++ av_packet_free(&in);
++
++ return ret;
++}
++
++static void asftoannexg_close(AVBSFContext *bsfc) {
++ ASFTOANNEXGBSFContext *bsfctx = bsfc->priv_data;
++ av_freep(&bsfctx->seq_header);
++ av_freep(&bsfctx->ep_header);
++}
++
++static const enum AVCodecID codec_ids[] = {
++ AV_CODEC_ID_VC1, AV_CODEC_ID_NONE,
++};
++
++FFBitStreamFilter ff_vc1_asftoannexg_bsf = {
++ .p.name = "vc1_asftoannexg",
++ .priv_data_size = sizeof(ASFTOANNEXGBSFContext),
++ .filter = asftoannexg_filter,
++ .close = asftoannexg_close,
++ .p.codec_ids = codec_ids,
++};
+diff --git a/libavcodec/vc1_asftorcv_bsf.c b/libavcodec/vc1_asftorcv_bsf.c
+new file mode 100644
+index 0000000000..02e510b4b6
+--- /dev/null
++++ b/libavcodec/vc1_asftorcv_bsf.c
+@@ -0,0 +1,105 @@
++/*
++ * copyright (c) 2010 Google Inc.
++ * copyright (c) 2017 Jacek Jendrzej port to 3.x
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "avcodec.h"
++#include "bytestream.h"
++#include "bsf.h"
++#include "bsf_internal.h"
++
++#define RCV_STREAM_HEADER_SIZE 36
++#define RCV_PICTURE_HEADER_SIZE 8
++
++typedef struct ASFTORCVBSFContext {
++ int frames;
++} ASFTORCVBSFContext;
++
++static int asftorcv_filter(AVBSFContext *ctx, AVPacket *out){
++ ASFTORCVBSFContext* bsfctx = ctx->priv_data;
++ AVPacket *in;
++ int keyframe;
++ int ret;
++ uint8_t* bs = NULL;
++
++ ret = ff_bsf_get_packet(ctx, &in);
++ if (ret < 0)
++ return ret;
++
++ keyframe = in->flags & AV_PKT_FLAG_KEY;
++
++ if (!bsfctx->frames) {
++ // Write the header if this is the first frame.
++ ret = av_new_packet(out, RCV_STREAM_HEADER_SIZE + RCV_PICTURE_HEADER_SIZE + in->size);
++ if (ret < 0)
++ goto exit;
++ bs = out->data;
++
++ // The following structure of stream header comes from libavformat/vc1testenc.c.
++ bytestream_put_le24(&bs, 0); // Frame count. 0 for streaming.
++ bytestream_put_byte(&bs, 0xC5);
++ bytestream_put_le32(&bs, 4); // 4 bytes of extra data.
++ bytestream_put_byte(&bs, ctx->par_in->extradata[0]);
++ bytestream_put_byte(&bs, ctx->par_in->extradata[1]);
++ bytestream_put_byte(&bs, ctx->par_in->extradata[2]);
++ bytestream_put_byte(&bs, ctx->par_in->extradata[3]);
++ bytestream_put_le32(&bs, ctx->par_in->height);
++ bytestream_put_le32(&bs, ctx->par_in->width);
++ bytestream_put_le32(&bs, 0xC);
++ bytestream_put_le24(&bs, 0); // hrd_buffer
++ bytestream_put_byte(&bs, 0x80); // level|cbr|res1
++ bytestream_put_le32(&bs, 0); // hrd_rate
++
++ // The following LE32 describes the frame rate. Since we don't care so fill
++ // it with 0xFFFFFFFF which means variable framerate.
++ // See: libavformat/vc1testenc.c
++ bytestream_put_le32(&bs, 0xFFFFFFFF);
++ } else {
++ ret = av_new_packet(out, RCV_PICTURE_HEADER_SIZE + in->size);
++ if (ret < 0)
++ goto exit;
++ bs = out->data;
++ }
++
++ // Write the picture header.
++ bytestream_put_le32(&bs, in->size | (keyframe ? 0x80000000 : 0));
++
++ // The following LE32 describes the pts. Since we don't care so fill it with 0.
++ bytestream_put_le32(&bs, 0);
++ memcpy(bs, in->data, in->size);
++
++ ++bsfctx->frames;
++
++ ret = av_packet_copy_props(out, in);
++
++exit:
++ av_packet_free(&in);
++
++ return ret;
++}
++
++static const enum AVCodecID codec_ids[] = {
++ AV_CODEC_ID_WMV3, AV_CODEC_ID_NONE,
++};
++
++FFBitStreamFilter ff_vc1_asftorcv_bsf = {
++ .p.name = "vc1_asftorcv",
++ .priv_data_size = sizeof(ASFTORCVBSFContext),
++ .filter = asftorcv_filter,
++ .p.codec_ids = codec_ids,
++};
--- /dev/null
+# Test case: The.Purge.2013.1080p.BluRay.x264.YIFY.mp4
+From 1c7b83f945e710a17a41ad9feb7dc929f26f2b0e Mon Sep 17 00:00:00 2001
+From: Jacek Jendrzej <satbaby@kawaii.com>
+Date: Wed, 28 Jun 2017 11:38:20 +0200
+Subject: [PATCH] fix sps/pps for cooli;This is commit that breaks seek in some
+ mkv.break with commit 6d2219e9f950b96279fd8464cc11c4d02518b629
+
+---
+ libavcodec/h264_mp4toannexb_bsf.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
+index 2822644b10..d57647d25c 100644
+--- a/libavcodec/h264_mp4toannexb_bsf.c
++++ b/libavcodec/h264_mp4toannexb_bsf.c
+@@ -242,6 +242,11 @@ static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *opkt)
+ if (!new_idr && unit_type == H264_NAL_IDR_SLICE && (buf[1] & 0x80))
+ new_idr = 1;
+
++ if (s->new_idr && unit_type == H264_NAL_SEI && s->idr_sps_seen && s->idr_pps_seen) {
++ s->idr_sps_seen = 0;
++ s->idr_pps_seen = 0;
++ }
++
+ /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */
+ if (new_idr && unit_type == H264_NAL_IDR_SLICE && !sps_seen && !pps_seen) {
+ if (ctx->par_out->extradata)
# FFMPEG | A complete, cross-platform solution to record, convert and stream audio and video
ifeq ($(BOXTYPE), armbox)
#FFMPEG_VER = 5.1.2
-FFMPEG_VER = 6.1.1
+FFMPEG_VER = 6.1.2
else ifeq ($(BOXTYPE), coolstream)
#FFMPEG_GIT = 2ba896f
#FFMPEG_VER = 3.3
-FFMPEG_VER = 6.1.1
+FFMPEG_VER = 6.1.2
endif
# FLAC stands for Free Lossless Audio Codec, an audio format similar to MP3, but lossless, meaning that audio is compressed in FLAC without any loss in quality