diff --git a/libavcodec/hevc_mp4toannexb_bsf.c b/libavcodec/hevc_mp4toannexb_bsf.c
index 09bce5b..98ff94a 100644
--- a/libavcodec/hevc_mp4toannexb_bsf.c
+++ b/libavcodec/hevc_mp4toannexb_bsf.c
@@ -24,6 +24,11 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
 
+#ifndef DISABLE_TANGUY_PATCH
+#include <stdbool.h>
+#include "libavutil/encryption_info.h"
+#endif
+
 #include "avcodec.h"
 #include "bsf.h"
 #include "bytestream.h"
@@ -36,6 +41,15 @@ typedef struct HEVCBSFContext {
     int      extradata_parsed;
 } HEVCBSFContext;
 
+#ifndef DISABLE_TANGUY_PATCH
+struct record {
+	AVPacket *pkt;
+	AVEncryptionInfo *src_info;
+	AVEncryptionInfo *dst_info;
+	size_t src_pos;
+};
+#endif
+
 static int hevc_extradata_to_annexb(AVBSFContext *ctx)
 {
     GetByteContext gb;
@@ -115,11 +129,230 @@ static int hevc_mp4toannexb_init(AVBSFContext *ctx)
     return 0;
 }
 
+#ifndef DISABLE_TANGUY_PATCH
+static AVEncryptionInfo *get_encryption_info(const AVPacket *pkt)
+{
+	uint8_t *val;
+	int len;
+
+	val = av_packet_get_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, &len);
+	if (!val)
+		return NULL;
+
+	return av_encryption_info_get_side_data(val, len);
+}
+#endif
+
+#ifndef DISABLE_TANGUY_PATCH
+static void record_start(AVBSFContext *ctx, struct record *r, AVPacket *pkt)
+{
+	memset(r, 0, sizeof(*r));
+
+	r->pkt = pkt;
+
+	r->src_info = get_encryption_info(pkt);
+
+	if (r->src_info && (r->src_info->subsample_count == 0)) {
+		r->src_info->subsample_count = 1;
+		r->src_info->subsamples = av_malloc(sizeof (r->src_info->subsamples[0]));
+		r->src_info->subsamples[0].bytes_of_clear_data = 0;
+		r->src_info->subsamples[0].bytes_of_protected_data = pkt->size;
+	}
+
+	if (r->src_info) {
+		r->dst_info = av_encryption_info_clone(r->src_info);
+
+		av_free(r->dst_info->subsamples);
+		r->dst_info->subsamples = NULL;
+
+		r->dst_info->subsample_count = 0;
+	} else {
+		r->dst_info = NULL;
+	}
+
+	r->src_pos = 0;
+}
+#endif
+
+#ifndef DISABLE_TANGUY_PATCH
+static void record_finish(AVBSFContext *ctx, struct record *r)
+{
+	enum AVPacketSideDataType type;
+	AVPacketSideData *side_data;
+	int side_data_elems;
+	uint8_t *data;
+	size_t size;
+	int i;
+
+	if (!r->src_info)
+		goto clean;
+
+	side_data = r->pkt->side_data;
+	side_data_elems = r->pkt->side_data_elems;
+
+	r->pkt->side_data = NULL;
+	r->pkt->side_data_elems = 0;
+
+	for (i = 0; i < side_data_elems; i++) {
+		type = side_data[i].type;
+
+		if (type == AV_PKT_DATA_ENCRYPTION_INFO) {
+			side_data[i].size = 0;
+			av_free(side_data[i].data);
+			side_data[i].data = NULL;
+			data = av_encryption_info_add_side_data(r->dst_info, &size);
+		} else {
+			size = side_data[i].size;
+			data = side_data[i].data;
+		}
+
+		av_packet_add_side_data(r->pkt, type, data, size);
+	}
+
+	av_free(side_data);
+	side_data = NULL;
+
+clean:
+	r->pkt = NULL;
+
+	av_encryption_info_free(r->src_info);
+	r->src_info = NULL;
+
+	av_encryption_info_free(r->dst_info);
+	r->dst_info = NULL;
+
+	r->src_pos = 0;
+
+	memset(r, 0, sizeof(*r));
+}
+#endif
+
+#ifndef DISABLE_TANGUY_PATCH
+static void record_skip(AVBSFContext *ctx, struct record *r, size_t count)
+{
+	if (!r->src_info)
+		return;
+
+	if (count == 0)
+		return;
+
+	r->src_pos += count;
+}
+#endif
+
+#ifndef DISABLE_TANGUY_PATCH
+static void record_append_clear_subsample(AVBSFContext *ctx, struct record *r, size_t count, bool squash)
+{
+	if (count == 0)
+		return;
+
+	if (squash
+	    && (r->dst_info->subsample_count > 0)
+	    && (r->dst_info->subsamples[r->dst_info->subsample_count - 1].bytes_of_protected_data == 0)) {
+		r->dst_info->subsamples[r->dst_info->subsample_count - 1].bytes_of_clear_data += count;
+	} else {
+		r->dst_info->subsamples = av_realloc(r->dst_info->subsamples,
+						     (r->dst_info->subsample_count + 1) * sizeof (r->dst_info->subsamples[0]));
+		r->dst_info->subsamples[r->dst_info->subsample_count].bytes_of_clear_data = count;
+		r->dst_info->subsamples[r->dst_info->subsample_count].bytes_of_protected_data = 0;
+		r->dst_info->subsample_count++;
+	}
+}
+#endif
+
+#ifndef DISABLE_TANGUY_PATCH
+static void record_append_protected_subsample(AVBSFContext *ctx, struct record *r, size_t count, bool squash)
+{
+	if (count == 0)
+		return;
+
+	if (squash
+	    && (r->dst_info->subsample_count > 0)) {
+		r->dst_info->subsamples[r->dst_info->subsample_count - 1].bytes_of_protected_data += count;
+	} else {
+		r->dst_info->subsamples = av_realloc(r->dst_info->subsamples,
+						     (r->dst_info->subsample_count + 1) * sizeof (r->dst_info->subsamples[0]));
+		r->dst_info->subsamples[r->dst_info->subsample_count].bytes_of_clear_data = 0;
+		r->dst_info->subsamples[r->dst_info->subsample_count].bytes_of_protected_data = count;
+		r->dst_info->subsample_count++;
+	}
+}
+#endif
+
+#ifndef DISABLE_TANGUY_PATCH
+static void record_insert(AVBSFContext *ctx, struct record *r, size_t count)
+{
+	if (!r->src_info)
+		return;
+
+	if (count == 0)
+		return;
+
+	record_append_clear_subsample(ctx, r, count, false);
+}
+#endif
+
+#ifndef DISABLE_TANGUY_PATCH
+static void record_copy(AVBSFContext *ctx, struct record *r, size_t count)
+{
+	const AVSubsampleEncryptionInfo *s;
+	AVSubsampleEncryptionInfo c;
+	size_t skip;
+	size_t op;
+
+	if (!r->src_info)
+		return;
+
+	if (count == 0)
+		return;
+
+	skip = r->src_pos;
+
+	for (s = &r->src_info->subsamples[0];
+	     s < &r->src_info->subsamples[r->src_info->subsample_count];
+	     s++) {
+
+		c = *s;
+
+		op = FFMIN(c.bytes_of_clear_data, skip);
+		skip -= op;
+		c.bytes_of_clear_data -= op;
+
+		op = FFMIN(c.bytes_of_protected_data, skip);
+		skip -= op;
+		c.bytes_of_protected_data -= op;
+
+		if (skip > 0)
+			continue;
+
+		op = FFMIN(c.bytes_of_clear_data, count);
+		count -= op;
+		c.bytes_of_clear_data -= op;
+
+		record_append_clear_subsample(ctx, r, op, true);
+		r->src_pos += op;
+
+		op = FFMIN(c.bytes_of_protected_data, count);
+		count -= op;
+		c.bytes_of_protected_data -= op;
+
+		record_append_protected_subsample(ctx, r, op, true);
+		r->src_pos += op;
+
+		if (count == 0)
+			break;
+	}
+}
+#endif
+
 static int hevc_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
 {
     HEVCBSFContext *s = ctx->priv_data;
     AVPacket *in;
     GetByteContext gb;
+#ifndef DISABLE_TANGUY_PATCH
+    struct record r;
+#endif
 
     int got_irap = 0;
     int i, ret = 0;
@@ -134,6 +367,10 @@ static int hevc_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
         return 0;
     }
 
+#ifndef DISABLE_TANGUY_PATCH
+    record_start(ctx, &r, in);
+#endif
+
     bytestream2_init(&gb, in->data, in->size);
 
     while (bytestream2_get_bytes_left(&gb)) {
@@ -143,6 +380,9 @@ static int hevc_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
 
         for (i = 0; i < s->length_size; i++)
             nalu_size = (nalu_size << 8) | bytestream2_get_byte(&gb);
+#ifndef DISABLE_TANGUY_PATCH
+	record_skip(ctx, &r, s->length_size);
+#endif
 
         nalu_type = (bytestream2_peek_byte(&gb) >> 1) & 0x3f;
 
@@ -166,10 +406,23 @@ static int hevc_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
 
         if (add_extradata)
             memcpy(out->data + prev_size, ctx->par_out->extradata, extra_size);
+#ifndef DISABLE_TANGUY_PATCH
+	record_insert(ctx, &r, extra_size);
+#endif
         AV_WB32(out->data + prev_size + extra_size, 1);
+#ifndef DISABLE_TANGUY_PATCH
+	record_insert(ctx, &r, 4);
+#endif
         bytestream2_get_buffer(&gb, out->data + prev_size + 4 + extra_size, nalu_size);
+#ifndef DISABLE_TANGUY_PATCH
+	record_copy(ctx, &r, nalu_size);
+#endif
     }
 
+#ifndef DISABLE_TANGUY_PATCH
+    record_finish(ctx, &r);
+#endif
+
     ret = av_packet_copy_props(out, in);
     if (ret < 0)
         goto fail;
