Opened 7 months ago

#10599 new defect

hls: Broken handling of partially encrypted http-streams

Reported by: hbehe Owned by:
Priority: normal Component: undetermined
Version: git-master Keywords: HLS AAC
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
When parsing a HLS file with an unencrypted file, followed by an encrypted file, decryption is skipped once. This only occurs with http due to broken keep-alive handling.

How to reproduce:
Given a m3u8/hls playlist description like

#EXTM3U
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:7
#EXT-X-KEY:METHOD=NONE
#EXTINF:6.014,title="Repro"
./chapter_01_0.aac
#EXT-X-KEY:METHOD=AES-128,URI="repro.key",IV=0x0665781e80339d0247b4d511e20996db
#EXTINF:5.991,title="Repro"
./chapter_01_1.aac
#EXT-X-ENDLIST

Parsing this as a local file works fine.

% ffmpeg -allowed_extensions ALL -i repro.m3u8 -c:v none -c:a copy repro.m4a
[hls @ 0x555caffef640] Skip ('#EXT-X-VERSION:3')
[hls @ 0x555caffef640] Opening './chapter_01_0.aac' for reading
Input #0, hls, from 'repro.m3u8':
  Duration: 00:00:12.01, bitrate: 0 kb/s
  Program 0 
    Metadata:
      variant_bitrate : 0
  Stream #0:0: Audio: aac (LC), 44100 Hz, mono, fltp
    Metadata:
      variant_bitrate : 0
Output #0, ipod, to 'repro.m4a':
  Metadata:
    encoder         : Lavf60.13.100
  Stream #0:0: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp
    Metadata:
      variant_bitrate : 0
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
[hls @ 0x555caffef640] Opening 'repro.key' for reading    
[hls @ 0x555caffef640] Opening 'crypto:./chapter_01_1.aac' for reading
[out#0/ipod @ 0x555cb0000440] video:0kB audio:100kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

Opening this via a http server fails

% ffmpeg -i http://127.0.0.1:8000/repro.m3u8 -c:v none -c:a copy repro.m4a
ffmpeg version N-112173-gfb05bc8eee Copyright (c) 2000-2023 the FFmpeg developers
  built with gcc 13.2.1 (GCC) 20230801
  configuration: --enable-debug --enable-openssl --optflags=0
  libavutil      58. 25.100 / 58. 25.100
  libavcodec     60. 27.100 / 60. 27.100
  libavformat    60. 13.100 / 60. 13.100
  libavdevice    60.  2.101 / 60.  2.101
  libavfilter     9. 11.100 /  9. 11.100
  libswscale      7.  3.100 /  7.  3.100
  libswresample   4. 11.100 /  4. 11.100
mime type is not rfc8216 compliant
[hls @ 0x55569dd3f580] Skip ('#EXT-X-VERSION:3')
[hls @ 0x55569dd3f580] Opening 'http://127.0.0.1:8000/chapter_01_0.aac' for reading
Input #0, hls, from 'http://127.0.0.1:8000/repro.m3u8':
  Duration: 00:00:12.01, bitrate: 0 kb/s
  Program 0 
    Metadata:
      variant_bitrate : 0
  Stream #0:0: Audio: aac (LC), 44100 Hz, mono, fltp
    Metadata:
      variant_bitrate : 0
Output #0, ipod, to 'repro.m4a':
  Metadata:
    encoder         : Lavf60.13.100
  Stream #0:0: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp
    Metadata:
      variant_bitrate : 0
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
[hls @ 0x55569dd3f580] Opening 'http://127.0.0.1:8000/repro.key' for reading
[http @ 0x55569dd46340] Opening 'crypto+http://127.0.0.1:8000/chapter_01_1.aac' for reading
[aac_adtstoasc @ 0x7fb5240009c0] Error parsing ADTS frame header!
[ipod @ 0x55569dd59e40] Error applying bitstream filters to an output packet for stream #0: Invalid data found when processing input
[aost#0:0/copy @ 0x55569dd4a600] Error submitting a packet to the muxer: Invalid data found when processing input
[out#0/ipod @ 0x55569dd4a200] Error muxing a packet
[out#0/ipod @ 0x55569dd4a200] video:0kB audio:64kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

Setting -http_persistent 0 makes it work again.

The error Error parsing ADTS frame header! in aac_adtstoasc stems from the second file not being decrypted at all and aacdec.c by chance finding 12 bits being 1.

There are various ways to make this "work", like closing the previous AVIOContext when encountering an encrypted file in open_url.
I wouldn't be happy writing such a patch and I don't think other maintainers would like another one of these hacks being piled on hls.c.

Related issue: https://trac.ffmpeg.org/ticket/8546

Tested with ffmpeg n6.0 and git from 2023-08-25
ffmpeg version N-112173-gfb05bc8eee Copyright (c) 2000-2023 the FFmpeg developers

built with gcc 13.2.1 (GCC) 20230801

Attachments (4)

repro.m3u8 (310 bytes ) - added by hbehe 7 months ago.
playlist descriptor
repro.key (16 bytes ) - added by hbehe 7 months ago.
decryption key
chapter_01_0.aac (49.0 KB ) - added by hbehe 7 months ago.
unencrypted part
chapter_01_1.aac (51.0 KB ) - added by hbehe 7 months ago.
encrypted part

Download all attachments as: .zip

Change History (4)

by hbehe, 7 months ago

Attachment: repro.m3u8 added

playlist descriptor

by hbehe, 7 months ago

Attachment: repro.key added

decryption key

by hbehe, 7 months ago

Attachment: chapter_01_0.aac added

unencrypted part

by hbehe, 7 months ago

Attachment: chapter_01_1.aac added

encrypted part

Note: See TracTickets for help on using tickets.