diff mbox series

[FFmpeg-devel] libavformat/movenc: Support encryption of H265 stream in AnnexB format

Message ID 20210301125348.318-1-vadim.bezdush@gmail.com
State New
Headers show
Series [FFmpeg-devel] libavformat/movenc: Support encryption of H265 stream in AnnexB format
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Вадим Бездушный March 1, 2021, 12:53 p.m. UTC
Add an ability to accept H265 AnnexB stream at encryption 
similar to how its done for H264 AnnexB stream. 

Steps to test:

1. Create h265 test files - mp4 and h265 AnnexB streams:
ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -c:v hevc input_h265.mp4
ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -c:v hevc -bsf:v hevc_mp4toannexb input_h265.h265

2. Encrypt and decrypt files. Put appropriate input file name here: input_h265.mp4 or input_h265.h265
ffmpeg -i input_h265.h265 -vcodec copy -acodec copy -encryption_scheme cenc-aes-ctr \
 -encryption_key 00000000000000000000000000000000 -encryption_kid 00000000000000000000000000000000 \
 encrypted_h265.mp4
ffplay -i encrypted_h265.mp4  -decryption_key 00000000000000000000000000000000

Signed-off-by: Vadym Bezdushnyi <vadim.bezdush@gmail.com>
---
 libavformat/movenc.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

Comments

Вадим Бездушный March 8, 2021, 10:05 p.m. UTC | #1
Ping.

This change is quite simple and should be quick to review. Feel free to ask
any questions

On Mon, 1 Mar 2021, 14:54 Vadym Bezdushnyi, <vadim.bezdush@gmail.com> wrote:

> Add an ability to accept H265 AnnexB stream at encryption
> similar to how its done for H264 AnnexB stream.
>
> Steps to test:
>
> 1. Create h265 test files - mp4 and h265 AnnexB streams:
> ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -c:v hevc
> input_h265.mp4
> ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -c:v hevc
> -bsf:v hevc_mp4toannexb input_h265.h265
>
> 2. Encrypt and decrypt files. Put appropriate input file name here:
> input_h265.mp4 or input_h265.h265
> ffmpeg -i input_h265.h265 -vcodec copy -acodec copy -encryption_scheme
> cenc-aes-ctr \
>  -encryption_key 00000000000000000000000000000000 -encryption_kid
> 00000000000000000000000000000000 \
>  encrypted_h265.mp4
> ffplay -i encrypted_h265.mp4  -decryption_key
> 00000000000000000000000000000000
>
> Signed-off-by: Vadym Bezdushnyi <vadim.bezdush@gmail.com>
> ---
>  libavformat/movenc.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> index 545b0885ae..0433968cd2 100644
> --- a/libavformat/movenc.c
> +++ b/libavformat/movenc.c
> @@ -5685,7 +5685,15 @@ int ff_mov_write_packet(AVFormatContext *s,
> AVPacket *pkt)
>                  return ret;
>              avio_write(pb, reformatted_data, size);
>          } else {
> -            size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
> +            if (trk->cenc.aes_ctr) {
> +                size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb,
> pkt->data, size);
> +                if (size < 0) {
> +                    ret = size;
> +                    goto err;
> +                }
> +            } else {
> +                size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0,
> NULL);
> +            }
>          }
>      } else if (par->codec_id == AV_CODEC_ID_AV1) {
>          if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
> @@ -5727,6 +5735,9 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket
> *pkt)
>              if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size
> > 4) {
>                  int nal_size_length = (par->extradata[4] & 0x3) + 1;
>                  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc,
> nal_size_length, pb, pkt->data, size);
> +            } else if(par->codec_id == AV_CODEC_ID_HEVC &&
> par->extradata_size > 21) {
> +                int nal_size_length = (par->extradata[21] & 0x3) + 1;
> +                ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc,
> nal_size_length, pb, pkt->data, size);
>              } else {
>                  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data,
> size);
>              }
> @@ -6711,7 +6722,8 @@ static int mov_init(AVFormatContext *s)
>
>          if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {
>              ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
> -                track->par->codec_id == AV_CODEC_ID_H264, s->flags &
> AVFMT_FLAG_BITEXACT);
> +                (track->par->codec_id == AV_CODEC_ID_H264 ||
> track->par->codec_id == AV_CODEC_ID_HEVC),
> +                s->flags & AVFMT_FLAG_BITEXACT);
>              if (ret)
>                  return ret;
>          }
> --
> 2.30.0
>
>
Вадим Бездушный March 11, 2021, 8:14 a.m. UTC | #2
Ping.

вт, 9 мар. 2021 г. в 00:05, Вадим Бездушный <vadim.bezdush@gmail.com>:

> Ping.
>
> This change is quite simple and should be quick to review. Feel free to
> ask any questions
>
> On Mon, 1 Mar 2021, 14:54 Vadym Bezdushnyi, <vadim.bezdush@gmail.com>
> wrote:
>
>> Add an ability to accept H265 AnnexB stream at encryption
>> similar to how its done for H264 AnnexB stream.
>>
>> Steps to test:
>>
>> 1. Create h265 test files - mp4 and h265 AnnexB streams:
>> ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -c:v hevc
>> input_h265.mp4
>> ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -c:v hevc
>> -bsf:v hevc_mp4toannexb input_h265.h265
>>
>> 2. Encrypt and decrypt files. Put appropriate input file name here:
>> input_h265.mp4 or input_h265.h265
>> ffmpeg -i input_h265.h265 -vcodec copy -acodec copy -encryption_scheme
>> cenc-aes-ctr \
>>  -encryption_key 00000000000000000000000000000000 -encryption_kid
>> 00000000000000000000000000000000 \
>>  encrypted_h265.mp4
>> ffplay -i encrypted_h265.mp4  -decryption_key
>> 00000000000000000000000000000000
>>
>> Signed-off-by: Vadym Bezdushnyi <vadim.bezdush@gmail.com>
>> ---
>>  libavformat/movenc.c | 16 ++++++++++++++--
>>  1 file changed, 14 insertions(+), 2 deletions(-)
>>
>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
>> index 545b0885ae..0433968cd2 100644
>> --- a/libavformat/movenc.c
>> +++ b/libavformat/movenc.c
>> @@ -5685,7 +5685,15 @@ int ff_mov_write_packet(AVFormatContext *s,
>> AVPacket *pkt)
>>                  return ret;
>>              avio_write(pb, reformatted_data, size);
>>          } else {
>> -            size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
>> +            if (trk->cenc.aes_ctr) {
>> +                size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb,
>> pkt->data, size);
>> +                if (size < 0) {
>> +                    ret = size;
>> +                    goto err;
>> +                }
>> +            } else {
>> +                size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0,
>> NULL);
>> +            }
>>          }
>>      } else if (par->codec_id == AV_CODEC_ID_AV1) {
>>          if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
>> @@ -5727,6 +5735,9 @@ int ff_mov_write_packet(AVFormatContext *s,
>> AVPacket *pkt)
>>              if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size
>> > 4) {
>>                  int nal_size_length = (par->extradata[4] & 0x3) + 1;
>>                  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc,
>> nal_size_length, pb, pkt->data, size);
>> +            } else if(par->codec_id == AV_CODEC_ID_HEVC &&
>> par->extradata_size > 21) {
>> +                int nal_size_length = (par->extradata[21] & 0x3) + 1;
>> +                ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc,
>> nal_size_length, pb, pkt->data, size);
>>              } else {
>>                  ret = ff_mov_cenc_write_packet(&trk->cenc, pb,
>> pkt->data, size);
>>              }
>> @@ -6711,7 +6722,8 @@ static int mov_init(AVFormatContext *s)
>>
>>          if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {
>>              ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
>> -                track->par->codec_id == AV_CODEC_ID_H264, s->flags &
>> AVFMT_FLAG_BITEXACT);
>> +                (track->par->codec_id == AV_CODEC_ID_H264 ||
>> track->par->codec_id == AV_CODEC_ID_HEVC),
>> +                s->flags & AVFMT_FLAG_BITEXACT);
>>              if (ret)
>>                  return ret;
>>          }
>> --
>> 2.30.0
>>
>>
Вадим Бездушный March 22, 2021, 9:29 a.m. UTC | #3
Ping.

чт, 11 мар. 2021 г. в 10:14, Вадим Бездушный <vadim.bezdush@gmail.com>:

> Ping.
>
> вт, 9 мар. 2021 г. в 00:05, Вадим Бездушный <vadim.bezdush@gmail.com>:
>
>> Ping.
>>
>> This change is quite simple and should be quick to review. Feel free to
>> ask any questions
>>
>> On Mon, 1 Mar 2021, 14:54 Vadym Bezdushnyi, <vadim.bezdush@gmail.com>
>> wrote:
>>
>>> Add an ability to accept H265 AnnexB stream at encryption
>>> similar to how its done for H264 AnnexB stream.
>>>
>>> Steps to test:
>>>
>>> 1. Create h265 test files - mp4 and h265 AnnexB streams:
>>> ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -c:v hevc
>>> input_h265.mp4
>>> ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -c:v hevc
>>> -bsf:v hevc_mp4toannexb input_h265.h265
>>>
>>> 2. Encrypt and decrypt files. Put appropriate input file name here:
>>> input_h265.mp4 or input_h265.h265
>>> ffmpeg -i input_h265.h265 -vcodec copy -acodec copy -encryption_scheme
>>> cenc-aes-ctr \
>>>  -encryption_key 00000000000000000000000000000000 -encryption_kid
>>> 00000000000000000000000000000000 \
>>>  encrypted_h265.mp4
>>> ffplay -i encrypted_h265.mp4  -decryption_key
>>> 00000000000000000000000000000000
>>>
>>> Signed-off-by: Vadym Bezdushnyi <vadim.bezdush@gmail.com>
>>> ---
>>>  libavformat/movenc.c | 16 ++++++++++++++--
>>>  1 file changed, 14 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
>>> index 545b0885ae..0433968cd2 100644
>>> --- a/libavformat/movenc.c
>>> +++ b/libavformat/movenc.c
>>> @@ -5685,7 +5685,15 @@ int ff_mov_write_packet(AVFormatContext *s,
>>> AVPacket *pkt)
>>>                  return ret;
>>>              avio_write(pb, reformatted_data, size);
>>>          } else {
>>> -            size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0,
>>> NULL);
>>> +            if (trk->cenc.aes_ctr) {
>>> +                size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb,
>>> pkt->data, size);
>>> +                if (size < 0) {
>>> +                    ret = size;
>>> +                    goto err;
>>> +                }
>>> +            } else {
>>> +                size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0,
>>> NULL);
>>> +            }
>>>          }
>>>      } else if (par->codec_id == AV_CODEC_ID_AV1) {
>>>          if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
>>> @@ -5727,6 +5735,9 @@ int ff_mov_write_packet(AVFormatContext *s,
>>> AVPacket *pkt)
>>>              if (par->codec_id == AV_CODEC_ID_H264 &&
>>> par->extradata_size > 4) {
>>>                  int nal_size_length = (par->extradata[4] & 0x3) + 1;
>>>                  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc,
>>> nal_size_length, pb, pkt->data, size);
>>> +            } else if(par->codec_id == AV_CODEC_ID_HEVC &&
>>> par->extradata_size > 21) {
>>> +                int nal_size_length = (par->extradata[21] & 0x3) + 1;
>>> +                ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc,
>>> nal_size_length, pb, pkt->data, size);
>>>              } else {
>>>                  ret = ff_mov_cenc_write_packet(&trk->cenc, pb,
>>> pkt->data, size);
>>>              }
>>> @@ -6711,7 +6722,8 @@ static int mov_init(AVFormatContext *s)
>>>
>>>          if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {
>>>              ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
>>> -                track->par->codec_id == AV_CODEC_ID_H264, s->flags &
>>> AVFMT_FLAG_BITEXACT);
>>> +                (track->par->codec_id == AV_CODEC_ID_H264 ||
>>> track->par->codec_id == AV_CODEC_ID_HEVC),
>>> +                s->flags & AVFMT_FLAG_BITEXACT);
>>>              if (ret)
>>>                  return ret;
>>>          }
>>> --
>>> 2.30.0
>>>
>>>
diff mbox series

Patch

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 545b0885ae..0433968cd2 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -5685,7 +5685,15 @@  int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
                 return ret;
             avio_write(pb, reformatted_data, size);
         } else {
-            size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
+            if (trk->cenc.aes_ctr) {
+                size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
+                if (size < 0) {
+                    ret = size;
+                    goto err;
+                }
+            } else {
+                size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
+            }
         }
     } else if (par->codec_id == AV_CODEC_ID_AV1) {
         if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
@@ -5727,6 +5735,9 @@  int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
             if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
                 int nal_size_length = (par->extradata[4] & 0x3) + 1;
                 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
+            } else if(par->codec_id == AV_CODEC_ID_HEVC && par->extradata_size > 21) {
+                int nal_size_length = (par->extradata[21] & 0x3) + 1;
+                ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
             } else {
                 ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
             }
@@ -6711,7 +6722,8 @@  static int mov_init(AVFormatContext *s)
 
         if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {
             ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
-                track->par->codec_id == AV_CODEC_ID_H264, s->flags & AVFMT_FLAG_BITEXACT);
+                (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC),
+                s->flags & AVFMT_FLAG_BITEXACT);
             if (ret)
                 return ret;
         }