Closed Bug 1870416 Opened 2 years ago Closed 3 months ago

mp4 file declared corrupt on linux - ERROR_DOM_MEDIA_DECODE_ERR (0x806e0004) - FFmpegVideoDecoder<58>

Categories

(Core :: Audio/Video, defect, P3)

Firefox 122
Unspecified
Linux
defect

Tracking

()

RESOLVED DUPLICATE of bug 1924070

People

(Reporter: brierjon, Unassigned)

References

()

Details

Attachments

(2 files)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0

Steps to reproduce:

Visit https://webglsamples.org/color-adjust/sample-video.mp4 on linux. This plays on Android and Windows.

Actual results:

States "Video can't be played because the file is corrupt"

Expected results:

Video should playback the video.

Output seen in terminal when when video is viewed when Firefox is launched via the command line (similar to seen in browser console when viewing as seen in the screenshot):
[Child 650282, MediaDecoderStateMachine #1] WARNING: Decoder=75208d666a00 Decode error: NS_ERROR_DOM_MEDIA_DECODE_ERR (0x806e0004) - virtual MediaResult mozilla::FFmpegVideoDecoder<58>::DoDecode(MediaRawData *, uint8_t *, int, bool *, MediaDataDecoder::DecodedData &): avcodec_send_packet error: Invalid data found when processing input: file /builds/worker/checkouts/gecko/dom/media/MediaDecoderStateMachineBase.cpp:166

The severity field is not set for this bug.
:jimm, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(jmathies)

I can verify this issue. When playback is attempted with Firefox, I'm seeing the following:

[h264 @ 0x7fc1d1760800] Invalid NAL unit size (0 > 318).
[h264 @ 0x7fc1d1760800] Error splitting the input into NAL units.
[h264 @ 0x7fc1d175f400] Invalid NAL unit size (0 > 55).
[h264 @ 0x7fc1d175f400] Error splitting the input into NAL units

Checking with ffprobe, the video file itself appears to be valid, with the sequence/picture parameter sets looking as follows:

[trace_headers @ 0x55e139a5d340] Extradata
[trace_headers @ 0x55e139a5d340] Sequence Parameter Set
[trace_headers @ 0x55e139a5d340] 0           forbidden_zero_bit                                          0 = 0
[trace_headers @ 0x55e139a5d340] 1           nal_ref_idc                                                11 = 3
[trace_headers @ 0x55e139a5d340] 3           nal_unit_type                                           00111 = 7
[trace_headers @ 0x55e139a5d340] 8           profile_idc                                          01000010 = 66
[trace_headers @ 0x55e139a5d340] 16          constraint_set0_flag                                        1 = 1
[trace_headers @ 0x55e139a5d340] 17          constraint_set1_flag                                        1 = 1
[trace_headers @ 0x55e139a5d340] 18          constraint_set2_flag                                        0 = 0
[trace_headers @ 0x55e139a5d340] 19          constraint_set3_flag                                        0 = 0
[trace_headers @ 0x55e139a5d340] 20          constraint_set4_flag                                        0 = 0
[trace_headers @ 0x55e139a5d340] 21          constraint_set5_flag                                        0 = 0
[trace_headers @ 0x55e139a5d340] 22          reserved_zero_2bits                                        00 = 0
[trace_headers @ 0x55e139a5d340] 24          level_idc                                            00010100 = 20
[trace_headers @ 0x55e139a5d340] 32          seq_parameter_set_id                                        1 = 0
[trace_headers @ 0x55e139a5d340] 33          log2_max_frame_num_minus4                                 011 = 2
[trace_headers @ 0x55e139a5d340] 36          pic_order_cnt_type                                          1 = 0
[trace_headers @ 0x55e139a5d340] 37          log2_max_pic_order_cnt_lsb_minus4                         011 = 2
[trace_headers @ 0x55e139a5d340] 40          max_num_ref_frames                                        010 = 1
[trace_headers @ 0x55e139a5d340] 43          gaps_in_frame_num_allowed_flag                              0 = 0
[trace_headers @ 0x55e139a5d340] 44          pic_width_in_mbs_minus1                             000011110 = 29
[trace_headers @ 0x55e139a5d340] 53          pic_height_in_map_units_minus1                        0001101 = 12
[trace_headers @ 0x55e139a5d340] 60          frame_mbs_only_flag                                         1 = 1
[trace_headers @ 0x55e139a5d340] 61          direct_8x8_inference_flag                                   1 = 1
[trace_headers @ 0x55e139a5d340] 62          frame_cropping_flag                                         1 = 1
[trace_headers @ 0x55e139a5d340] 63          frame_crop_left_offset                                      1 = 0
[trace_headers @ 0x55e139a5d340] 64          frame_crop_right_offset                                     1 = 0
[trace_headers @ 0x55e139a5d340] 65          frame_crop_top_offset                                       1 = 0
[trace_headers @ 0x55e139a5d340] 66          frame_crop_bottom_offset                                  011 = 2
[trace_headers @ 0x55e139a5d340] 69          vui_parameters_present_flag                                 1 = 1
[trace_headers @ 0x55e139a5d340] 70          aspect_ratio_info_present_flag                              1 = 1
[trace_headers @ 0x55e139a5d340] 71          aspect_ratio_idc                                     00000001 = 1
[trace_headers @ 0x55e139a5d340] 79          overscan_info_present_flag                                  0 = 0
[trace_headers @ 0x55e139a5d340] 80          video_signal_type_present_flag                              0 = 0
[trace_headers @ 0x55e139a5d340] 81          chroma_loc_info_present_flag                                0 = 0
[trace_headers @ 0x55e139a5d340] 82          timing_info_present_flag                                    1 = 1
[trace_headers @ 0x55e139a5d340] 83          num_units_in_tick            00000000000000000000000000000001 = 1
[trace_headers @ 0x55e139a5d340] 115         time_scale                   00000000000000000000000000110000 = 48
[trace_headers @ 0x55e139a5d340] 147         fixed_frame_rate_flag                                       1 = 1
[trace_headers @ 0x55e139a5d340] 148         nal_hrd_parameters_present_flag                             0 = 0
[trace_headers @ 0x55e139a5d340] 149         vcl_hrd_parameters_present_flag                             0 = 0
[trace_headers @ 0x55e139a5d340] 150         pic_struct_present_flag                                     0 = 0
[trace_headers @ 0x55e139a5d340] 151         bitstream_restriction_flag                                  1 = 1
[trace_headers @ 0x55e139a5d340] 152         motion_vectors_over_pic_boundaries_flag                     1 = 1
[trace_headers @ 0x55e139a5d340] 153         max_bytes_per_pic_denom                                     1 = 0
[trace_headers @ 0x55e139a5d340] 154         max_bits_per_mb_denom                                       1 = 0
[trace_headers @ 0x55e139a5d340] 155         log2_max_mv_length_horizontal                         0001010 = 9
[trace_headers @ 0x55e139a5d340] 162         log2_max_mv_length_vertical                           0001010 = 9
[trace_headers @ 0x55e139a5d340] 169         max_num_reorder_frames                                      1 = 0
[trace_headers @ 0x55e139a5d340] 170         max_dec_frame_buffering                                   010 = 1
[trace_headers @ 0x55e139a5d340] 173         rbsp_stop_one_bit                                           1 = 1
[trace_headers @ 0x55e139a5d340] 174         rbsp_alignment_zero_bit                                     0 = 0
[trace_headers @ 0x55e139a5d340] 175         rbsp_alignment_zero_bit                                     0 = 0
[trace_headers @ 0x55e139a5d340] Picture Parameter Set
[trace_headers @ 0x55e139a5d340] 0           forbidden_zero_bit                                          0 = 0
[trace_headers @ 0x55e139a5d340] 1           nal_ref_idc                                                11 = 3
[trace_headers @ 0x55e139a5d340] 3           nal_unit_type                                           01000 = 8
[trace_headers @ 0x55e139a5d340] 8           pic_parameter_set_id                                        1 = 0
[trace_headers @ 0x55e139a5d340] 9           seq_parameter_set_id                                        1 = 0
[trace_headers @ 0x55e139a5d340] 10          entropy_coding_mode_flag                                    0 = 0
[trace_headers @ 0x55e139a5d340] 11          bottom_field_pic_order_in_frame_present_flag                0 = 0
[trace_headers @ 0x55e139a5d340] 12          num_slice_groups_minus1                                     1 = 0
[trace_headers @ 0x55e139a5d340] 13          num_ref_idx_l0_default_active_minus1                        1 = 0
[trace_headers @ 0x55e139a5d340] 14          num_ref_idx_l1_default_active_minus1                        1 = 0
[trace_headers @ 0x55e139a5d340] 15          weighted_pred_flag                                          0 = 0
[trace_headers @ 0x55e139a5d340] 16          weighted_bipred_idc                                        00 = 0
[trace_headers @ 0x55e139a5d340] 18          pic_init_qp_minus26                                         1 = 0
[trace_headers @ 0x55e139a5d340] 19          pic_init_qs_minus26                                         1 = 0
[trace_headers @ 0x55e139a5d340] 20          chroma_qp_index_offset                                  00101 = -2
[trace_headers @ 0x55e139a5d340] 25          deblocking_filter_control_present_flag                      1 = 1
[trace_headers @ 0x55e139a5d340] 26          constrained_intra_pred_flag                                 0 = 0
[trace_headers @ 0x55e139a5d340] 27          redundant_pic_cnt_present_flag                              0 = 0
[trace_headers @ 0x55e139a5d340] 28          rbsp_stop_one_bit                                           1 = 1
[trace_headers @ 0x55e139a5d340] 29          rbsp_alignment_zero_bit                                     0 = 0
[trace_headers @ 0x55e139a5d340] 30          rbsp_alignment_zero_bit                                     0 = 0
[trace_headers @ 0x55e139a5d340] 31          rbsp_alignment_zero_bit                                     0 = 0

The 318 byte and 55 byte packets from the Firefox log appear immediately after:

[trace_headers @ 0x55e139a5d340] Packet: 318 bytes, key frame, pts 0, dts 0, duration 1000.
[trace_headers @ 0x55e139a5d340] Slice Header
[trace_headers @ 0x55e139a5d340] 0           forbidden_zero_bit                                          0 = 0
[trace_headers @ 0x55e139a5d340] 1           nal_ref_idc                                                11 = 3
[trace_headers @ 0x55e139a5d340] 3           nal_unit_type                                           00101 = 5
[trace_headers @ 0x55e139a5d340] 8           first_mb_in_slice                                           1 = 0
[trace_headers @ 0x55e139a5d340] 9           slice_type                                            0001000 = 7
[trace_headers @ 0x55e139a5d340] 16          pic_parameter_set_id                                        1 = 0
[trace_headers @ 0x55e139a5d340] 17          frame_num                                              000000 = 0
[trace_headers @ 0x55e139a5d340] 23          idr_pic_id                                                  1 = 0
[trace_headers @ 0x55e139a5d340] 24          pic_order_cnt_lsb                                      000000 = 0
[trace_headers @ 0x55e139a5d340] 30          no_output_of_prior_pics_flag                                0 = 0
[trace_headers @ 0x55e139a5d340] 31          long_term_reference_flag                                    0 = 0
[trace_headers @ 0x55e139a5d340] 32          slice_qp_delta                                      000010011 = -9
[trace_headers @ 0x55e139a5d340] 41          disable_deblocking_filter_idc                               1 = 0
[trace_headers @ 0x55e139a5d340] 42          slice_alpha_c0_offset_div2                                  1 = 0
[trace_headers @ 0x55e139a5d340] 43          slice_beta_offset_div2                                      1 = 0
[trace_headers @ 0x55e139a5d340] Packet: 55 bytes, pts 1000, dts 1000, duration 1000.
[trace_headers @ 0x55e139a5d340] Slice Header
[trace_headers @ 0x55e139a5d340] 0           forbidden_zero_bit                                          0 = 0
[trace_headers @ 0x55e139a5d340] 1           nal_ref_idc                                                10 = 2
[trace_headers @ 0x55e139a5d340] 3           nal_unit_type                                           00001 = 1
[trace_headers @ 0x55e139a5d340] 8           first_mb_in_slice                                           1 = 0
[trace_headers @ 0x55e139a5d340] 9           slice_type                                              00110 = 5
[trace_headers @ 0x55e139a5d340] 14          pic_parameter_set_id                                        1 = 0
[trace_headers @ 0x55e139a5d340] 15          frame_num                                              000001 = 1
[trace_headers @ 0x55e139a5d340] 21          pic_order_cnt_lsb                                      000001 = 1
[trace_headers @ 0x55e139a5d340] 27          num_ref_idx_active_override_flag                            1 = 1
[trace_headers @ 0x55e139a5d340] 28          num_ref_idx_l0_active_minus1                                1 = 0
[trace_headers @ 0x55e139a5d340] 29          ref_pic_list_modification_flag_l0                           0 = 0
[trace_headers @ 0x55e139a5d340] 30          adaptive_ref_pic_marking_mode_flag                          0 = 0
[trace_headers @ 0x55e139a5d340] 31          slice_qp_delta                                      000010001 = -8
[trace_headers @ 0x55e139a5d340] 40          disable_deblocking_filter_idc                               1 = 0
[trace_headers @ 0x55e139a5d340] 41          slice_alpha_c0_offset_div2                                  1 = 0
[trace_headers @ 0x55e139a5d340] 42          slice_beta_offset_div2                                      1 = 0

MP4Box can parse the NAL sample info as well without throwing any errors. I'm not sure if this is a case of us parsing a header incorrectly or if it's something else. :padenot, would you have any ideas here?

Severity: -- → S3
Flags: needinfo?(padenot)
Priority: -- → P3

Since we can reproduce easily, the best router is to make a pernosco recording of this and then we can find what's going on.

Flags: needinfo?(padenot)
Flags: needinfo?(jmathies)

Can you make a recording?

Flags: needinfo?(azebrowski)

Here's a link to an earlier recording -- I'll paste some information from an offline conversation for context as well.

The FFmpeg source lines for the Invalid NAL unit size errors are in h2645_parse.h:131-135 and
h264dec.c:613-617. Checking in Pernosco, in FFmpegDataDecoder::ProcessDecode, aSample->mBuffer.mLength is equal to 57 and 320, two more than the numbers reported in the error messages. There are two NAL units before the errors which I've seen decoded successfully, but it appears that nothing after that succeeds:

[h264 @ 0x7fc58f37cc00] nal_unit_type: 7(SPS), nal_ref_idc: 3
[h264 @ 0x7fc58f37cc00] nal_unit_type: 8(PPS), nal_ref_idc: 3

For context, I'll paste some relevant lines from get_nalsize where the Invalid NAL unit size error messages originate:

static inline int get_nalsize(int nal_length_size, const uint8_t *buf,
                              int buf_size, int *buf_index, void *logctx)
{ 
    // ...                              
    nalsize = ((unsigned)nalsize << 8) | buf[(*buf_index)+1]

    if (nalsize <= 0 || nalsize > buf_size - *buf_index) {
           av_log(logctx, AV_LOG_ERROR,
                  "Invalid NAL unit size (%d > %d).\n", nalsize, buf_size - *buf_index);
           return AVERROR_INVALIDDATA;
    }

When we get the Invalid NAL unit size (0 > 55) error message, nal_length_size is 2, with the corresponding bytes in the buffer equal to 0x0000:

Thread 6 hit Breakpoint 1.1, get_nalsize (logctx=0x7f686d01fc00, buf_index=<synthetic pointer>, buf_size=320, buf=0x7f686d07fe00 "", nal_length_size=2) at src/libavcodec/h2645_parse.h:124

(rr) p *buf_index
$24 = 0

(rr) p buf[*buf_index]@nal_length_size
$38 = "\000"

According to this blog post:

The decoder has no idea on how to search the boundaries of the NAL units. So, a three-byte or four-byte start code, 0x000001 or 0x00000001, is added at the beginning of each NAL unit.

If we go a byte past nal_length_size, we can see that we have 0x000001:

(rr) p buf[*buf_index]@nal_length_size+1
$25 = "\000\000\001"

So, I thought maybe this is supposed to be a "three-byte start code" that we're off-by-one with? When we hit the Invalid NAL unit size error in H264.cpp, nal_unit_type is equal to 170, as per Pernosco. If we check page 65 of the spec, it looks like 31 is the largest value of nal_unit_type we should be seeing. So, something's broken by the time we get to that point. It seems like the next place to look might be in MP4TrackDemuxer::GetNextSample or in H264::GetFrameType, or possibly further up the stack? I'm unfamiliar with the code here for packetizing incoming data packets, so I'm open to ideas here. I did verify that this isn't a regression with mozregression.

Flags: needinfo?(azebrowski)

Sounds plausible, we need to look one layer up in the demuxer, it shouldn't be too hard because we have a recording. jhlin can probably answer all questions there is to ask about NALs and all that.

I noticed that the sample video has 2-byte NALU length size, and the sample was converted to 4-byte length size at [1]. However, the value of lengthSizeMinusOne in the AVCC record in extra data wasn't updated. It seems to me that when we modify the length size in the bitstream, the AVCC record should also be changed accordingly, or the decoder won't get the correct NALU length if the implementation derives the size from the extra data.

[1] https://searchfox.org/mozilla-central/rev/4fe00e0322377316390da6faa2d645cae53d08f4/dom/media/platforms/agnostic/bytestreams/AnnexB.cpp#481

Tested today to check if any of the work done on Linux has had impact on the original reporting system.

The test file at the provide url on this issue playback results:
fails as reported on Firefox Release 136.0 build 20250227124745
works as expected on Firefox Nightly 138.0a1 build 20250312091925

Not sure what edit(s) are making this function now on nightly, but I look forward to the 138 release if this remains!

Looks like this might be related to the NALU work in bug 1924070? We might be able to close this out as a dupe in that case. :jolin, could you please confirm?

Flags: needinfo?(jolin)

Yes, this is the same as bug 1924070. Closing as duplicate.

Status: UNCONFIRMED → RESOLVED
Closed: 3 months ago
Duplicate of bug: 1924070
Flags: needinfo?(jolin)
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: