Opened 4 years ago

Last modified 4 years ago

#8815 new defect

pssh boxes are ignored when present before trak box

Reported by: panpawel88 Owned by:
Priority: normal Component: avformat
Version: git-master Keywords: mov
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
I would like to extract "Encryption initialization data" from a mp4 container, but the ffmpeg does not parse pssh boxes if they are before any trak box.

How to reproduce:

$ ffprobe -show_streams oops_cenc-20121114-142.mp4 
ffprobe version N-98270-g29ea4e1b3c Copyright (c) 2007-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
  configuration: --disable-optimizations --enable-ffplay
  libavutil      56. 55.100 / 56. 55.100
  libavcodec     58. 93.100 / 58. 93.100
  libavformat    58. 47.100 / 58. 47.100
  libavdevice    58. 11.100 / 58. 11.100
  libavfilter     7. 86.100 /  7. 86.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'oops_cenc-20121114-142.mp4':
  Metadata:
    major_brand     : dash
    minor_version   : 0
    compatible_brands: iso6avc1mp41
    creation_time   : 2012-11-14T07:35:10.000000Z
  Duration: 00:04:02.70, start: 0.000000, bitrate: 264 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressive), 426x240, 5 kb/s, 23.97 fps, 23.97 tbr, 90k tbn, 47.95 tbc (default)
    Metadata:
      creation_time   : 2012-11-14T07:35:10.000000Z
      handler_name    : VideoHandler
[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=Main
codec_type=video
codec_time_base=1877/90000
codec_tag_string=avc1
codec_tag=0x31637661
width=426
height=240
coded_width=432
coded_height=240
closed_captions=0
has_b_frames=0
sample_aspect_ratio=N/A
display_aspect_ratio=N/A
pix_fmt=yuv420p
level=21
color_range=unknown
color_space=unknown
color_transfer=unknown
color_primaries=unknown
chroma_location=left
field_order=progressive
timecode=N/A
refs=1
is_avc=true
nal_length_size=4
id=N/A
r_frame_rate=45000/1877
avg_frame_rate=45000/1877
time_base=1/90000
start_pts=0
start_time=0.000000
duration_ts=21843105
duration=242.701167
bit_rate=5543
max_bit_rate=N/A
bits_per_raw_sample=8
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:creation_time=2012-11-14T07:35:10.000000Z
TAG:language=und
TAG:handler_name=VideoHandler
[/STREAM]

As you see, ffprobe does not list:

[SIDE_DATA]
side_data_type=Encryption initialization data
[/SIDE_DATA]

but a sample content contains PSSH boxes:

$mp4dump oops_cenc-20121114-142.mp4
...
[moov] size=8+1703
  [mvhd] size=12+96
    timescale = 90000
    duration = 0
    duration(ms) = 0
  [pssh] size=12+40
    system_id = [ed ef 8b a9 79 d6 4a ce a3 c8 27 dc d5 1d 21 ed]
    data_size = 20
  [pssh] size=12+744
    system_id = [9a 04 f0 79 98 40 42 86 ab 92 e6 5b e0 88 5f 95]
    data_size = 724
  [pssh] size=12+36
    system_id = [58 14 7e c8 04 23 46 59 92 e6 f5 2c 5c e8 c3 cc]
    data_size = 16
  [mvex] size=8+32
    [trex] size=12+20
      track id = 1
      default sample description index = 1
      default sample duration = 0
      default sample size = 0
      default sample flags = 0
  [trak] size=8+691
    [tkhd] size=12+80, flags=3
      enabled = 1
      id = 1
      duration = 0
      width = 426.000000
      height = 240.000000
...

Please take a look at libavformat/mov.c:

static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVEncryptionInitInfo *info, *old_init_info;
    uint8_t **key_ids;
    AVStream *st;
    uint8_t *side_data, *extra_data, *old_side_data;
    size_t side_data_size;
    int ret = 0, old_side_data_size;
    unsigned int version, kid_count, extra_data_size, alloc_size = 0;

    if (c->fc->nb_streams < 1)
        return 0;

When a pssh box is found, the 'c->fc->nb_streams < 1' condition is true, because a trak box is not yet found.

I'm not sure if the assumption that "a pssh box must be after a trak box" is correct. IMHO, pssh boxes are related to all streams defined in moov box, not only the last one, but I cannot find any confirmation in the specification.

Attachments (1)

oops_cenc-20121114-142.mp4 (1.7 KB ) - added by panpawel88 4 years ago.

Download all attachments as: .zip

Change History (3)

by panpawel88, 4 years ago

Attachment: oops_cenc-20121114-142.mp4 added

comment:1 by Carl Eugen Hoyos, 4 years ago

Keywords: mov added

comment:2 by Chris Miceli, 4 years ago

I took a look at ISO 23001-7 and on page 7 it describes the PSSH atom. I'm not sure about if I can quote it directly (legally) however it does state that the PSSH box only needs to be a part of the moov/moof atom, not that the order is meant to be after the trak atom.

Regarding a fix, it would more than likely involve trying to process this after the trak somehow (I'm very new to the codebase) but the side data can only be added to streams which "exist" at the time of processing the PSSH box.

This would actually be a problem in a case where you have multiple streams, one with PSSH after the trak and one before because the code will just grab the last stream.

Note: See TracTickets for help on using tickets.