Hi,

I've been testing IAMF stream-copy and hit something I can't tell is intended. 
I'd rather ask than file, since I've already been wrong once on this tracker.

Stream-copying an IAMF file with Opus essence drops 
num_samples_to_trim_at_start from the Audio Frame OBUs. The demuxer reads it 
correctly — ffprobe -show_packets reports skip_samples: 312 — but it isn't 
written back out, and the output is 21 bytes shorter (7 substreams × 3 bytes: 
the trimming flag cleared, two ULEB128 fields 
dropped).num_samples_to_trim_at_end survives.

The relevant part of libavformat/iamf_writer.c:

c
if (side_data && side_data_size >= 10) {
    skip_samples    = AV_RL32(side_data);
    discard_padding = AV_RL32(side_data + 4);
}

if (codec_config->codec_id == AV_CODEC_ID_OPUS) {
    // IAMF's num_samples_to_trim_at_start is the same as Opus's pre-skip.
    skip_samples = pkt->dts < 0
        ? av_rescale(-pkt->dts, 48000, pkt->time_base.den)
        : 0;
    discard_padding = av_rescale(discard_padding, 48000, pkt->time_base.den);
}
The comment suggests the intent is that the value is always the Opus pre-skip 
and can be re-derived, which holds on the encode path where the first DTS is 
negative by the encoder delay. On copy the demuxer gives dts = 0 and puts the 
value in side data, so the branch yields 0.

My question is whether that's deliberate. Two things make me unsure:

discard_padding in the same block is only rescaled, not overwritten — so 
end-trim survives a copy and start-trim doesn't, which reads more like an 
oversight than a rule.
The override is inside the Opus case, so FLAC/PCM/AAC essence would keep the 
side-data value. That asymmetry seems unintentional.
If num_samples_to_trim_at_start is only ever the pre-skip, then nothing is lost 
— a decoder gets the same number from the codec config, and I've confirmed 
ffmpeg decodes such a copy identically. But if it can legitimately exceed the 
codec delay (an edit point, concatenation, a stream starting mid-content), the 
copy loses information that isn't recorded anywhere else. On a file with 
trim_start 600 and pre_skip 120, ffmpeg decodes the original to 479,520 frames 
and the copy to 480,000 — 480 extra leading samples, remainder byte-identical.

Would something like this be the right shape, or am I misreading the intent?

c
if (codec_config->codec_id == AV_CODEC_ID_OPUS) {
    if (!side_data && pkt->dts < 0)
        skip_samples = av_rescale(-pkt->dts, 48000, pkt->time_base.den);
    discard_padding = av_rescale(discard_padding, 48000, pkt->time_base.den);
}
Same behaviour on n8.1.2 and master c6309b5c; happy to send a sample file or 
test a patch.

Thanks for any info.

-James
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to